We at
Perfect Solutions last week wrote the 100th API. During all this time, at the cost of a rake, crutches, bicycles and refactoring, we realized that we had developed an excellent strategy "how to write an API and stop pain and suffering."
This post is about versioning, support, bugfixing and full life cycle API.
Under the cut there are no photos with a lot of traffic, no silver bullets, there is not even a picture to attract attention - only a useful squeeze of our experience. Under the cat methodology developed on the actual experience of development, stuffed cones and broken rakes.
Product approach
The API is not a “set of functions for everyone”, not a “set for solving any tasks”, not “make and forget”.
')
An API is a product, with a product that developers will use. You will not be able to "sell" them a bad API, passing it off as a good one. Time will answer all questions.
What is the API product approach? This means that the API consists of features
and bugs . Features should be simple and atomic: one API method is perceived as one feature. Whether a feature, user registration through the API? Yes, feature! Whether a feature, sending push notifications? Feature!
And this means that all API methods must be
thought out, described, developed and tested - to go through a full development cycle. The biggest trouble in terms of the attitude of developers to the API is its lack of thought.
Atomicity of operations
If your API does in one method 3 INSERT in a DBMS - there must be a transaction. If it does not exist, it will not just cause problems, but also cause problems that are
not found and not reproducible from the interface .
And another important point in the concept of atormarnost. The feature is atomic. If, when registering a new user from the API, roles must be specified (from the system of rights), then the API method is required to do both things to register a user in one request:
- Create user
- Do assign the transferred list of roles.
For example, here is such a method, in the case of yii2:
public function actionRegister($username, $password, array $roleNames) { ... }
Verification of all incoming parameters and compliance with protocols
Like any data received from the user, everything that comes to the API must be validated. The API is used by developers, but they are the same users, people.
Standard http-responses corresponding to realities is an important point to simplify support and debug. Invalid request, non-validation - “400 Bad Request”, Internal error - “500 Internal Server Error”. This is very important for logging (in the nginx logs) and repairing all future bugs. If the API always gives status 200, it will be very difficult to find the cause of errors in the logs.
You will fix bugs
You do not throw out the API, do not "make a new version later." You will fix bugs in this version of the API, in this code, and right tomorrow.
I say this to the fact that, like any product, an API is something that will have to be debugged, tested and maintained. So there is the most common set of rules:
- Follow the protocol (at least Status Code)
- Log everything - on the API side, log requests and responses, on the client side - the same. Funny moment - it can also be different ;-)
- Test it, review the code and remember that the API is a product whose users are developers.
- Make a special parameter for debugging - so that on the client side you can get not only the response from the API, but also all debug information. Next to the answer.
Never believe that you invented the API versioning method
API versioning helps to lose backward compatibility in new methods without discarding old methods, leaving them in the old version. The Internet offers a lot of ways to version API. Ways for different frameworks, approaches and all the rest, but there is no silver bullet. For that is, a store in which almost any bullet easily fits is a location in nginx.
location /api/v1/ { ... } location /api/v2/ { ... }
Such an approach will not only allow the old API to be thrown out at the right time, but will also allow the new API to be moved to another server, to a separate application, or anywhere else. This is not a "solution to all problems", it is a box in which you can add up a lot of your decisions that will change with time.
Document Drive Development
Documenting the API is often a pain. Documentation is almost always irrelevant, and tools like swagger still require support. This issue is easily solved if obryat grocery approach - start with the documentation. That's right when you start a task in your jira / redmine - there and describe everything you want from the API. Directly in the documentation format.
Put a new method on the combat server - just copy the documentation from the task to your documentation repository. And voila - your documentation is always relevant.
OP as analogy
Write simple API methods. Imagine writing a function on Erlang. A decent part of the problems are "methods of all Russia", "method for the whole" or any method overloaded with logic.
API methods must be atomic, but sufficient. And too small broken and the reverse side - will lead to problems.
Good luck!
I briefly outlined
our subjective experience of developing an API, but did not provide any meaningful code — you will still have your code.
But all this is short in the form of theses:
- Product approach
- Atomicity of operations
- Verification of all incoming parameters and compliance with protocols
- Log everything
- Never believe that you invented the API versioning method
- Document Drive Development
- OP as analogy