4 ms·
I really have a problem with the concept of the Serializer in DRF. It handles so much that has nothing to do with serialization. It performs something like de
by skatenerd 12y ago
I really have a problem with the concept of the Serializer in DRF. It handles so much that has nothing to do with serialization. It performs something like de-serialization, where it takes an incoming dictionary and turns it into an ORM object. The docs even recommend using its ".save()" method. Save? on a Serializer?
I think it's a really cool concept if you think of it as more of a Lens. The so-called serializer lets you declare properties of "fields", and these properties will influence both the native-to-ORM conversion, as well as the ORM-to-native conversion.
- norbert_mate 12y agoI agree with you. It is a bit weird that a serializer can interact with the database but what it basically does: hides the database interaction.
- skatenerd 12y agoout of curiosity, how often do you find yourself reading the DRF source code to figure out whats happening?
- norbert_mate 12y ago"The best documentation is the source code" :-) . I use to read it but sometimes is really hard to understand what's going on. As you said the serializer does a lot of thing.
- tomchristie 12y agoThe model / model manager layer is the right place at which to design your state changing API. REST framework absolutely you to work with the grain there. Some good practice I'd recommend... * Write the `create()` and/or `update()` methods explicitly on the serializer class. * Push logic into the model and model manager where possible and only have the serializer `.save()` as a thin layer on top of that. That way a serializer class still has all the behavior it needs to map both ways between persisted objects and their corresponding native python representations, but you still have a well separated model API.
- skatenerd 12y agoInteresting. In practice, I have started following a pattern where I have two Serializer classes - a "serializer" and a "deserializer". The "deserializer"'s job is to perform validation and type coercion of incoming requests. It returns a "native" dictionary, which the application code then saves to ORM. The "serializer" is basically a presentation layer. It calls out to other nested serializers [this is awesome!], and it throws in convenience-fields that make the API response easier to consume. This pattern makes it a little bit less "magical", and it's easier to distinguish between the API's "incoming" behavior and its "outgoing" behavior.
- morphyn 12y agoTheir API/role is very similar to the `forms` in standard Django. I agree with you that they handle too much stuff and that saving to the database has nothing to do in a serializer, just like it has nothing to do in a form. But I also think it's a very good choice to follow common Django practices, so that codebases stay somewhat consistent, and new users are able to understand the concepts very quickly.
- ComNik 12y agoI was thinking the exact same thing when I first read about DRF's Serializers. Also I don't quite get why serialization is always expected to work automatically, at least not in the context of mapping a business layer to an API layer (e.g. for JSON consumption), as those domains don't have to map directly onto each other. Therefore, for an ongoing project I've implemented something along the lines of your idea (if I got that correctly), by describing API-Layer models in terms of properties, which are just named sets of pure lambdas. The most general property only requires a single one to compute the property value from an input business-model. This allows for some very nice things, especially with regards to API-level functionality like support for nested ?expand=, ?only=, and such niceties.
- IgorPartola 12y agoThe big problem for me is that serializers are bidirectional. They should only work in one direction: server to client. Client to server should be either handled by a wrapper around Django form or by a separate deserializer type. Why? Take a simple example: you have a game character model which consists of things like name, color, and a set of randomly generated attributes such as strength, agility, etc. Now, you wan the server to generate the attributes, but not the name and the color. You write your code, do a POST to /characters/ and BAM: {"strength": ["This field is required."], ...}. Now you have to tell the serializer that this field is not required... Oh, and try customizing error messages or providing customer error conditions... It's just not fun. I think this is the weakest part of DRF.