Essa apresentação aconteceu no 17 encontro dos usuários de Rails de PE - Frevo on Rails. Nela, eu abordo 4 tópicos importantes na hora de implementar APIs: Rest, Consistencia, Versionamento e Segurança.
If there's one thing that has gained wide adoption, it's RESTful principles. These were first introduced by Roy Felding in Chapter 5 of his dissertation on network based software architectures. The key principles of REST involve separating your API into logical resources. These resources are manipulated using HTTP requests where the method (GET, POST, PUT, PATCH, DELETE) has specific meaning.A resource should be nouns (not verbs!) that make sense from the perspective of the API consume.REST is a simple way to organize interactions between independent systems
It is a collection of resources, with four defined aspects
Client–server:A uniform interface separates clients from servers. This separation of concerns means that, for example, clients are not concerned with data storage, which remains internal to each server, so that the portability of client code is improved. Servers are not concerned with the user interface or user state, so that servers can be simpler and more scalable. Servers and clients may also be replaced and developed independently, as long as the interface between them is not altered.Stateless: The client–server communication is further constrained by no client context being stored on the server between requests. Each request from any client contains all of the information necessary to service the request, and any session state is held in the client.Cacheable: As on the World Wide Web, clients can cache responses. Responses must therefore, implicitly or explicitly, define themselves as cacheable, or not, to prevent clients reusing stale or inappropriate data in response to further requests. Well-managed caching partially or completely eliminates some client–server interactions, further improving scalability and performance.Layered system: A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. Intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. They may also enforce security policies.Uniform interface:The uniform interface between clients and servers, discussed below, simplifies and decouples the architecture, which enables each part to evolve independently. The four guiding principles of this interface are detailed below.
To prevent an API consumer from having to hit the API again for an updated representation, have the API return the updated (or created) representation as part of the response.
Status codes tell the client application what it needs to do with the response in general terms. For example, if your API returns a 401 you know you need a logged in user. If the API returns a 403 you know the user you’re working with doesn’t have sufficient authorization. If the API returns a 418 you know that the API is telling you it’s a teapot and was probably written by knobs.Validation error in Rails = 422 unprocessableentityDelete in Rails = 204 No Content
Just like an HTML error page shows a useful error message to a visitor, an API should provide a useful error message in a known consumable format. The representation of an error should be no different than the representation of any resource, just with its own set of fields.API that return 200 but error in the response code.
Always version your API. Versioning helps you iterate faster and prevents invalid requests from hitting updated endpoints. It also helps smooth over any major API version transitions as you can continue to offer old API versions for a period of time.There are mixed opinions around whether an API version should be included in the URL or in a header. Academically speaking, it should probably be in a header. However, the version needs to be in the URL to ensure browser explorability of the resources across versions (remember the API requirements specified at the top of this post?).
A RESTful API should be stateless. This means that request authentication should not depend on cookies or sessions. Instead, each request should come with some sort authentication credentials.
HTTP Basic authentication (BA) implementation is the simplest technique for enforcing access controls to web resources because it doesn't require cookies, session identifier and login pages. Rather, HTTP Basic authentication uses static, standard HTTP headers which means that no handshakes have to be done in anticipation.One thing to watch out for is that the credentials are sent as clear text so we should be sure to use a secure connection or maybe a digest connection.
API keys/secrets are usually a long series of random characters that are difficult to guess. Username/password are typically much smaller in length, use common words, are generally insecure, and can be subject to brute force and dictionary attacks.
It provides a much needed solution for security web APIs without requiring users to share their usernames and passwordsOAuth provides a mechanism for users to grant access to private data without sharing their private credentials (username/password). Many sites have started enabling APIs to use OAuth because of its security and standard set of libraries.
O que é uma API mesmo?
Application Programming Interface
Biblioteca que inclui especificações para rotinas,
estruturas de dados, objetos, classes e variáveis
Características de boas APIs
Fácil de aprender e memorizar
Dificilmente usada de maneira errada
Tópicos para hoje
REpresentational State Transfer
Um padrão arquitetural para sistemas hipermídias
Tipo de mídia
Operações (Método HTTP)
ons_timeline.jsonTipo de mídia
2 URLs base por recurso
• GET /tickets - recupera conjunto de tickets
• GET /tickets/12 - recupera o ticket #12
• POST /tickets - cria um novo ticket
• PUT /tickets/12 - atualiza ticket #12
• DELETE /tickets/12 - remove ticket #12
Sistema em camadas
API implementada usando
princípios HTTP e REST
> nandokakimoto@Development$ rails new blog
> nandokakimoto@blog$ rails generate scaffold Post name:string title:string
> nandokakimoto@blog$ rake routes
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
> nandokakimoto@blog$ rake routes
GET /api/v1/products(.:format) api/v1/posts#index
POST /api/v1/products(.:format) api/v1/posts#create
GET /api/v1/products/new(.:format) api/v1/posts#new
GET /api/v1/products/:id/edit(.:format) api/v1/posts#edit
GET /api/v1/products/:id(.:format) api/v1/posts#show
PUT /api/v1/products/:id(.:format) api/v1/posts#update
DELETE /api/v1/products/:id(.:format) api/v1/posts#destroy
> nandokakimoto@blog$ rake routes
GET /api/v2/posts(.:format) api/v2/posts#index
POST /api/v2/posts(.:format) api/v2/posts#create
GET /api/v2/posts/new(.:format) api/v2/posts#new
GET /api/v2/posts/:id/edit(.:format) api/v2/posts#edit
GET /api/v2/posts/:id(.:format) api/v2/posts#show
PUT /api/v2/posts/:id(.:format) api/v2/posts#update
DELETE /api/v2/posts/:id(.:format) api/v2/posts#destroy