mercoledì 28 settembre 2016

MyBatis + Guice and the Transactional annotation

I wasn't a huge fan of MyBatis, mainly because I hate working with XML. For the project we are working on, we wanted to use the same objects for persistence and to pass as messages to an actor system (Akka) to do some work in parallel, so we really wanted our data objects to be immutable, this removed Hibernate from the picture.
MyBatis turned our to be very reliable and not as painful as I thought when it came to creating the mappers.
As a dependency injection we decided to use Guice, and the integration between the two proved to be seamless. The only problems started showing up when we created some integrations tests to check whether the Transactional annotations were working. The bugs were many, and hard to debug, so I decided to create a dummy project to test how the Transactional annotation works once and for all.
In our project, we are using different databases in the application so we have to use private modules, which introduces a whole bunch of caveats, but before digging into it, let's start with what the internet says about this.


The Transactional annotation documentation

The official Guice wiki doesn't say much about what affect the Transactional annotation, only that:


The only restriction is that these methods must be on objects that were created by Guice and they must not be private.

Fair enough. MyBatis-Guice's documentation ads some more informations about nested transactions, but still doesn't mention issues with private modules. The documentation is very poor for such an important piece of the library 


Setting up the environment

For these tests, I created a simple environment: a MyBatis mapper that doesn't really do anything, a service implementing an interface in which I inject the mapper. I also inject the SqlSessionManager in the service to check whether the method is being executed inside a transaction by calling sqlSessionManager.isManagedSessionStarted().

This is the mapper:



This is the service interface:



This is the service:



The tests


The tests simply create an injector, get an instance of the service and call addValue on it. The method will throw an AssertionError if a transaction was not started, indicating that the Transactional annotation was ignored. 
Let's ignore the interface for now and focus on the DummyService implementation.
For the first test I just create a normal MyBatis module and bind the DummyMapper. This test passes.



Now, let's try to run a public method calling a private method annotated with Transactional. As the Guice documentation mentioned, this test fails.

Let's add private modules to the picture. I will bind the mapper and expose the mapper in a private service and then try to get an instance of the DummyService. This doesn't work, as the module has to know about the service for the Transactional annotation to work.


To make it work, you need to expose the DummyService explicitely:


Now let's see what happens with interfaces. Let's try binding and exposing the interface instead of the implementation directly, and see if the private module method still works (it does)


So far, everything is working as expected (more or less), but then something weird happened. I had a bug I was trying to fix and I was growing desperate, I tried to explicitely expose Mapper and SqlSessionManager on top of the DummyService, to get closer to our product. I thought it wouldn't make a difference but it did, and this test fails:

Even stranger, it doesn't fail if I bind and expose the implementation directly:

I probably stumbled upon a weird bug, I will update this post if something comes up, but the documentation on this topic is seriously lacking.

This test, farther away from our implementation, reproduces the issue more clearly.




Update


The MyBatis/Guice team promptly got back to me, apparently it's a known Guice issue, but it's "expected behavior". Pretty much what's happening is that Guice is instantiating the service in the private module's parent, and the annotations defined in the private module (including Transactional) are ignored. Suggested workarounds: bind instances directly when they use the Transactional annotation, or use requireExplicitBindings()



mercoledì 20 gennaio 2016

Which framework should I use to develop a REST application in Python?

Recently, I started looking into REST solutions in Python. Although the possibilities are many, it was hard to find many satisfactory products to be used to develop REST applications in a simple, clean way.
To feet my needs, the final product had to satisfy the following criteria:

  • it has to support Python 3 cleanly;
  • it should enforce as little design constraints as possible on the resulting application;
  • as a consequence of the previous point, it should make it easy to swap the chosen solution with another at will;
  • optional, but good to have: it should make it possible and not too awkward to use a DI library on top of it.

Here is a list of the frameworks I checked out.

Django REST framework

This one seems to be one of the most adopted, probably because of the popularity of Django. Django REST Framework is a Django plugin that adds some functionality to handle REST more easily. It's very well documented and it's not too hard to customize the logic of specific endpoints, or plug in additional code on the resources. 
Like with anything in Django, most of the basics work out of the box, and everything is easy and cool as long as you follow the Django (in this case, Django REST framework) way to do things. The design of your applications must follow the rules strictly, and obviously you need to use the entirety of the Django framework, or write some very awkward code.
This makes it almost impossible not only to change the REST layer, but everything else in your application will be entangled in Django. 

Flask RESTful

Flask RESTful is more lightweight than Django REST framework, and seems to be well documented and supported. I like the OO approach and the extendibility. The problem with it is Flask: in the documentation, they basically suggest against using Python 3. This makes me very uncomfortable using the framework in general, let alone an extension on top of it.
Another thing I don't like is the fact that you need to extend Resource to create a resource, and you need to pass the class arguments as dictionaries using resource_class_kwargs and resource_class_args: it makes it awkward to inject services and to use a DI library.

Werkzeug

Werkzeug is the WSGI library Flask is based upon. It's a very thin layer, so it doesn't force your design too much. The only complain may be that the layer is almost too thin: it doesn't do much to hide WSGI. Another big point against it is that, according to their website, support for python 3 is still highly experimental.

Falcon

Falcon ended up being my framework of choice. I love its minimalistic approach, and the fact that it uses duck typing when creating resources, and that it takes initialized classes when configuring the resulting application: it makes it very easy to use DI with it, encouraging the developers to follow the single responsibility principle. It's also advertised as being extremely fast compared to other frameworks, although I'm not really concerned with performance at this level when coding with Python. And it supports Python 3! 
I'll publish a post with my approach to REST development with Falcon in the near future.

Conclusion

Obviously, this post is not an evaluation on the quality of these frameworks per se, but more a collection of thoughts on which library fits my needs the most. I'd like to get your feedback and feel free to suggest more frameworks.