Introduction
In the
first part, I began to share my observations about the implementation of HTTP / GET in REST. In this one, let's try to consider the issues of versioning and architecture. Let's start?
Versioning is something your API is useless without.
Remember past publication?
URL / URN / URI / resource / slug - we have considered all these concepts. What is more?
All addressing from the first article is synthetic, it has nothing to do with the real project.
THIS IS NOT TO WRITE API!It is impossible because the URI is completely missing such an important thing as
versioning .
Why URI? Why not a URL? Why not URN? Because our API provides access to the states of objects within collections. Those. it doesn't matter to us which URL (read “on which server”) or which URN (read “what kind of backend”) the object will have, it is important for us to know what version of the object we are using.
The API versioning theme flashes in various sources, but, in my opinion, it is modeled not very well. It is believed that versioning will allow not to mix different implementations of API (i.e. versions associate with URL / URN).
And now the
revelation : And who forbade the daemon (URN) running on the server (URL) serving the collection (resource), version v2, to accept objects of version v1? From the fact that the object has version v1, has it ceased to be valid? User object ceased to be a user? Unclear? OK. Let's take it in order.
Architecture
From the materials of
Wikipedia in the section "REST architecture" there are the following lines:
The client can interact not directly with the server, but with an arbitrary number of intermediate nodes. In this case, the client may not be aware of the existence of intermediate nodes, except for the cases of transfer of confidential information.
there is a list of goals that we are trying to achieve
- scalability
- portability of components
- ease of change
- ability to evolve
What did the author want to achieve? No, "world peace" is understandable, but still ...
Let's try to decompose the problem and use the “typical” horizontal scaling solutions:
- We implement many servers serving client requests via DNS.
- In each server we have balancing on sets of backends on different internal servers.
- In each backend from 1 to n collections
')
And now the question for a million: how the collections communicate with each other? The logical question is “WHY?”, But is ready to answer with a “synthetic” example:
Given :
- Server # 1 with backend in which there is a collection of users
- Server # 2 with backend in which there is a collection of groups
Task : When adding a user to the groups collection, check that the user is present in the users collection. When users are received from groups, this user still exists in the users collection, and if not, remove them from the groups collection and not pass information about the user to the user.
Let us leave the subtleties of the URL / URN / URI / etc and what is transmitted over them. The question is how to achieve a consistent state in a distributed system? The first thing that comes to mind is to use the same REST to the next collection, but where can I get a fault-tolerant server with caching and load balancing ?! STOP! So everything is already there! Take it and use it!
Hmm ... ok, we have a scalable http-cluster (yes, I know that this is not a cluster in the strict sense of the word), but what about the versioning? Moreover, it’s not rational in a distributed system that supports communication between the participants to make a garden with the stack of the old API (read “make another cluster for less”). And, in some cases, drag backends between versions. For example, in version 2, only the user collection has changed and contacts has been added. How will groups move to version 2?
To critics
Predicting questions, I will try to clarify some points.
What is it all about? What kind of nonsense?The thing is that versioning is a collection property and not an API. Otherwise, no scaling.
You have a problem in architecture. It should be something like this: / groups / group_name / users / user_nameYes, it is, but:
... as long as the user can be in the same group, otherwise you will have 2 or more URIs returning the same object.
... as long as the user is obliged to have a group, otherwise you will have to enter fake groups (default, global, system, all - is it really informative?)
REST for communications in a distributed system? Are you out of your mind ?!Do not worry, I know that “white people” for this purpose use asynchronous clustered message brokers over transport channels with a guaranteed band and other delights of corporate systems. This is a "synthetic" example, and not so bad in 3-5 servers.
Is that all you have for versioning?Oh no! I just began!
PS Friends, at 3:00, which means it's time to sleep. I ask everyone to speak in comments. Without your feedback, writing is sooo hard.