📜 ⬆️ ⬇️

Admin as unit test for HTTP API

Greetings, colleagues. Many services on the Internet provide an HTTP API for developers. There are a lot of articles on how to do it right, not less stories how it turned out wrong, and a mighty handful of criticism of what others did. It is difficult to make a good API - it constantly tries to fall out of Miller’s wallet , acquire cyclic dependencies among entities and shove a poor developer into the Procrustean bed of usage scenarios “as developers see them”. I’ll add my own five kopecks - under the cut is a funny, but working way that we use to tame our rather big HTTP API

The best frameworks and APIs are extracted from live projects.


On the Internet, I often see the statement that the successful frameworks and APIs were extracted by the authors from working, commercial projects. How did the Django framework come about? The authors have made many news sites. At some point, they realized that part of the code was creeping from project to project. Brought this code to a separate library - it turned out a web framework. How did the Amazon API come about? Did interaction interfaces between internal services. After a while, the API stabilized, began to change less and less, and finally, it was made available to external clients.

When extracting something from a living project, we don’t have to try to paint on use cases “on paper”, which is usually not very good. Despite the brainstorming crutches, diagrams, and wikis, people are not well adapted to keeping new complex systems in mind, and many attempts to come up with a complex “on paper” API end in complete rework several months after the release.

But what to do if the project is initially a platform, and no “commercial projects” from which its parts can be extracted do not exist in nature yet? Many managers in such cases offer development teams to “mock up” potential solutions and develop APIs for such mockups. Alas, the layout “invented“ from the head ”is often very different from what real users will create. Not because it was badly invented, but because of the limitations of our brain on the amount of information held in focus.
')

Admin as reference application


Many years ago, when we were just starting to create voximplant, we had a large stack of clients from customers and an understanding of the fact that the first time a good API would not work. But really wanted to. And during the next brainstorming, a strange idea was born: to make the admin panel for developers not on the backend, as they did for most projects then, but on the frontend. And so that the admin panel for all its functions uses the same HTTP API that we give to our clients.

A huge plus of this approach is that the API design evolves with the admin panel. At the beginning it is a clean sheet with the button “add user”. To make the button work, we make the AJAX call and the / AddUser method from the server side. Add a user ID input field — add a user_name paired argument for the API method — and so on, until the main functionality is created.

Of course, this approach is not suitable for everyone. The development of “software” is a very large area. There is a development to customer specification, when the entire API is designed entirely by a specially trained team of architects. There are situations when the API reflects only a small part of the platform functionality available for external developers to the sandbox. There is a contract development, when everything needs to be thought out and calculated in advance in order to predict the time and budget.

Nevertheless, this method helped us very well. And, as far as I see on the Internet, more and more services with a developed API adhere to the principle of “eat your own dog food”, using these APIs and for developing your own admins and services. While a startup does not have comprehensive documentation and training materials for all occasions, the client’s question “how to do this” can always be answered - “take actions in the admin panel and look in chrome dev tools what requests and with what arguments it performs”. This approach works - and it works well.

Further evolution: how to use AttachPhoneNumber


An admin is a good thing, but for many services it allows you to do only the most popular operations, while “complex” cases remain under the hood or are accessible by API. As an example, I will show our API function / AttachPhoneNumber which allows you to rent a phone number in order to manage incoming calls to this number in the future using javascript scripts. When buying a number in the admin panel, you can filter the available numbers by countries / types / cities, select the number you like or specify the number of rooms to rent, and then click on the “buy” button:



If you look at our documentation for the corresponding API method, you can easily find a match between what we see in the interface and what can be passed to the API function:





As you can see, all these values ​​are reflections of the corresponding form fields and were added as functionality was added: at first there was the opportunity to buy by number, then we added the choice of the number of numbers, which drew the need to indicate which numbers the customer was interested in, then partners appeared and the possibility of purchase the number is outdated - and so on.

How to get a number in Japan and answer the call


A practical example of how the creators of applications on our platform can use the API, guided by the admin as the reference implementation. Suppose we want to rent a room in Tokyo and javascript when calling this number. Only for demonstration purposes, of course.

First we need to find out the number of available rooms - suddenly Tokyo ended? For authorization, we use the account identifier and key from the voximplant admin settings, and to request the number of numbers, the specially trained GetPhoneNumbers method:

curl "https://api.voximplant.com/platform_api/GetNewPhoneNumbers/?account_id=1&api_key=2&country_code=JP&phone_category_name=GEOGRAPHIC&phone_region_id=8384" 

In response, we get an authorization error json, in which the total_count field contains the number of available numbers, at the time of this writing - 224 pieces. There are numbers in Tokyo. To rent a number, we use the AttachPhoneNumber method I have already described, just like the admin panel does. This will differ from the previous request only by the name api endpoint and the phone_count parameter, indicating that we want to rent exactly one number:

 curl "https://api.voximplant.com/platform_api/AttachPhoneNumber/?account_id=1&api_key=2&country_code=JP&phone_category_name=GEOGRAPHIC&phone_region_id=8384&phone_count=1" 

After a couple of seconds of thinking, we will get JSON with the parameters of the leased number, it looks like this:

 { "result":1, "phone_numbers":[ { "phone_number":"81345793488", "verification_status":"VERIFIED", "phone_id":9033 } ] } 

In the answer we can see the number itself (I got 81345793488). In this number, “+81” is the Japan code, “3” is the Tokyo code (note that it does not match the region identifier for Tokyo, which we specified as “8384” because the region identifier is an internal telecom identifier) ​​and “ 45793488 ”- the actual number itself. To take a call on him and do something useful, you need to associate it with one of the voximplant applications - which can also be created via the API. An example of such a command that will connect the rented number with the “foo” application (yes, I have such an application. It says “hello” and hangs up):

 curl "https://api.voximplant.com/platform_api/BindPhoneNumberToApplication/?account_id=1api_key=2&phone_number=81345793488&application_name=foo" 

We hope that this small case will add a little trick to your piggy bank of web development techniques - perhaps sometime in the future, this approach will save you from a lot of sleepless nights spent on the design of the “perfect api”. In the comments, I am traditionally ready to respond to non-constructive criticism, answer tricky questions and just chat on the subject of API design and development.

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


All Articles