📜 ⬆️ ⬇️

A little bit about how to organize a web service API

There was a task to organize a web service to which regular clients will turn from a browser and other web services.

Suppose I sell theater tickets to customers. The client can only be an agency that has an account with me on the service. Agencies are small, in which the aunt sits and handles in a personal account with the help of a baruser, makes a purchase of a ticket, as well as large ones, in which everything is automated. The big ones want to be able to connect to me using the API and make a purchase.

You can watch prices on tickets, pre-book, redeem reservations, return purchased ones and delete reservations.
')
Question: what is the best way to organize an API?

I'm going to organize a web service and generally a service on Ruby on Rails, but I will try to set out general principles, where it is possible to bypass the implementation. I will try to briefly present what I read in the process of preparing for the creation of the API, and also provide references to the original sources.

API Organization Principles


By architecture / ideology options: REST , SOAP , XML-RPC and others.

After reading a lot, I chose REST, because it gives less freedom in places where it is not needed: the name of the methods and the method of calling this method. In short: my tickets now are resources. Each action with a ticket is available by a unique combination of HTTP-method + URL. For example, a preliminary reservation (in fact, creating a ticket order): POST / orders.xml, deleting an order for ticket tickets DELETE / order / 1.xml, and viewing prices GET /prices.xml.

More about REST on Habré and Wikipedia .

The best article about the REST API and Ruby on Rails, in the public domain, is the chapter about ActiveResource in the Rails 3 in a Nutshell book, courtesy of O'Reilly. It describes the situation from the point of view of both the REST API client and the server. It is very useful to read to understand why it is necessary to use the RESTful API. In addition, it describes a very interesting implementation of the REST API client ActiveResource included in Ruby On Rails. ActiveResource is ported to some other languages ​​and will be useful not only for rubists.

The rest of the read articles, minus trifles, are invested in the one above.

Implementation

By implementation, I really liked the concept offered by Rails by default, and with all its might exploiting the principle of DRY : generating API responses (XML, JSON) in the same controllers as generating responses to the user (html).

By the way, for the implementation of DRY, there is a useful plugin acts_as_api , which allows to save a lot on XML-templates and a new feature of Ruby on Rails 3.

There are several explanatory branches on Stackoverflow on this topic, for example this one .

Implementing API as a separate module

There are several DSL for organizing the API. For example, Grape and, if anyone needs to integrate Grape and Ruby on Rails, then go here: martinciu.com/2011/01/mounting-grape-api-inside-rails-application.html

Authentication


Authentication options \ authorization mass: Basic , using tokens, using certificates, Oauth .

As far as I understood Oauth, in our case it does not fit, because there is no client account on my server that could allow the agent to log in. There is no end user at all, I don’t know about it, so the Oauth option is no longer available.

The most reliable in terms of security, but apparently the most difficult to implement, both on the client and on the server, is certificate-based authentication.

The most basic option is basic (essentially, a username and password: user : password@api.myserver.ru/orders.xml).

I chose the authentication option for stateless tokens, because it allows the user to log in to the browser as a username and password and create orders and, at the same time, to create orders using the same user (but using a token) using an automated web service. I want each of my agents to have exactly one user on my server.

Yes, of course, do not forget that since we started to log in, then our API should be wrapped in HTTPS to avoid authorization data leaks. I plan to give my agents the opportunity to regenerate the API-key in their personal accounts, if they consider that it is time.

In addition, I chose the option stateless token, passed as a POST or GET parameter. There is another option to push the token into HTTP headers, not a parameter (this is a more REST option, but a little more difficult to implement), as is done with Amazon . But it seemed to me that in this case the game of implementation is not worth the candle. There is no particular gain for this option (well, maybe, except that the structure of the request
It will be a little more RESTful), and there is a trouble.

Literature on the organization of authorization / authentication of the web service:
stackoverflow.com/questions/6134082/restful-web-service-how-to-authenticate-requests-from-other-services
stackoverflow.com/questions/939836/service-based-authentication-using-tokens

Implementation

For Ruby on Rails, there is a wonderful devise plugin for which there is a module for authentication by token . Literally, a couple of lines - and everything is ready.

UPD. Colleagues, minus the topic, you can unsubscribe with what you disagree. And then half the value of the topic - in the discussion, and you keep silent!

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


All Articles