What is the best practice for serializing foreign key fields in a REST-ful api

I want to write a Django application with a REST-ful api. The Django REST system offers three built-in model serializers: ModelSerializer, which serializes to something like this.

{ 'normal_field': 'value', 'foreign_key_field': 42 } 

and a HyperlinkedModelSerializer that serializes to something like this

 { 'normal_field': 'value', 'foreign_key_field': 'http://domain/api/myothermodel/11' } 

My question is whether there is another good way to serialize the data so that the client directly knows which fields should be allowed and which should not.

Example: a client who receives this

 { 'foo': 'http://domain/api/myothermodel/11', 'bar': 'http://otherdomain/api/myothermodel/12' } 

doesn't know if foo or bar should be a solvable foreign key field, not a simple URL. Sort of:

 { 'foo': 'http://domain/api/myothermodel/11', # Here the client might know that this is only a plain url. 'bar': { '_foreignkey': true, # Tells the client that this field should behave as a foreign key which has to be resolved first 'url': 'http://otherdomain/api/myothermodel/12' } } 

Is there any standard or best practice? Or is it best that the client does not know this from JSON, but from another code that it has or receives from the server?

Update: Additionally you can add which path is best for some well-known client libraries such as AngularJS.

+5
source share
1 answer

It seems you are after a self-describing and researched web API service, which is actually the main feature of the original REST concept, called Hypermedia as an application state engine (HATEOAS) . In fact, a HATEOAS-compatible web service does not rely on any prior knowledge of system resources other than the initial URL entry point.

This differs from a service-oriented architecture (SOA) , where individual services are mostly unrelated and require prior knowledge of their existence to combine several service calls to perform a task with several, possibly related resources.

Most references to the REST API are actually not completely RESTful, and should be more accurately described as web APIs, since they are more in line with the SOA design: a set of URLs for both specific instances and collections of instances of a particular type. It will also include the use of various HTTP verbs (GET, PATCH, POST, PUT) for various actions to perform these resources. The Django REST Framework (DRF) actually has a page on this topic with links to some great resources on true RESTful design, including Roy Fielding's dissertation:

http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas

I would suggest that the current use of the term "REST API" refers to the revelation of many developers who implement a truly RESTful service, are far from trivial and in many cases will be overly designed for a particular use case. Perhaps this is a good example of "excellence as the enemy of good." When using AngularJS as a client environment for interacting with the Django backend via DRF, this is especially true. There is nothing in the AngularJS framework to analyze a RESTful design to automatically provide various application states for a given resource. In addition, the same developers will usually be responsible for the JavaScript and Python code, so the lack of a self-describing API is not a serious obstacle to development.

Regarding the implementation of a truly RESTful API in JSON, there are several projects trying to facilitate this, namely Hypertext Application Language (HAL) and Related JSON Data (JSON-LD) . However, I don't know that DRF natively supports any of them, so you probably have to archive serializers to match one of them, or generate your own implementation of Django REST.

Finally, any design you choose to fully document the API is usually a good idea. This is true whether the API is a website or in some native programming language. Part of the attractiveness for sharing the problems that the web API provides is that third parties can consume resources to create applications or pipelines that you didn’t take into account, not to mention the benefits of maintainability of future changes in the code base for your project. interesting projects mentioned on the DRF website to help document the API. Swagger is especially awesome, developed by the same developer who provided the older Danguage Docs package for Django.

+4
source

Source: https://habr.com/ru/post/1202091/


All Articles