I am building an API using Django Rest Framework, and I'm trying to make it as RESTful as possible. Following this question (and also this question on SoftwareEngineering), I have described a number of resources that my API endpoints will expose, such as an Invoice
that can be seen at the following URL: /api/v1/invoices/<invoicenumber>/
However, I am having trouble relating the RESTful design principles to the concrete workings of Django Rest Framework. It is unclear to me what constitues a resource: the model, the serializer or the view?
In particular, I am confused about the correct place to implement my calculate_total()
method. In a regular Django application it would certainly live in the the Invoice model:
class InvoiceModel(models.Model):
def calculate_total(self):
# do calculation
return total
Although the actual calculation could be complex, the "total" is conceptually a part of the representation of the Invoice. In this sense, the resource is more equivalent to the InvoiceSerializer
:
class InvoiceSerializer(serializers.Serializer):
total = serializers.SerializerMethodField()
def get_total(self, obj):
# do calculation
return total
Finally, the resource will always be accessed by a view. So you could also argue that the view is actually the resource, while the serializer and the model are simply implementation details:
class InvoiceView(APIView):
def calculate_total(self, obj):
# do calculation
return total
If I would have to designate one of the above classes as the canonical representation of the Invoice as a resource, which one would it be? Should I implement my method on the model class, the serializer class, or the view class? Or perhaps I am overthinking this and any one of them will do?
Well, although I agree that there might be different solutions, In this case I would definitely go with the model. As the resource and the place where to put the function.
In the case of the function, it could even be implemented as a calculated attribute of the invoice. Actually, to me TOTAL looks more like an attribute that a method.
Anyway, it seems interesting to me your train of thought and how you get to the other two options, serializer and the view.
I think that the model it is definitely a resource. In this case for me, the invoice resource is the model. So I would say that every model that your API is going to publish, is a resource.
I also think that whenever the resource is not directly related to a single model, the view could be considered the resource.
Now, the serializer is an enigma to me. I can't think of a case that it could be think it as a resource.