Quero compartilhar as melhores práticas que tenho encontrado para o design de uma REST API. Neste artigo, fiz uma breve compilação de pontos essenciais para a tríade: recurso, usabilidade e experiência.
Um bom design é difícil de ser aplicado e requer prática, principalmente para impedir a repetição de trabalho e ajudar os desenvolvedores a entenderem exatamente como consumir e manipular os recursos da API, isto depende da Developer Experience (DX).
DX é UX aplicada para desenvolvedores, porquê nós somos pessoas também
A DX é uma extensão do UX que se concentra diretamente em quem desenvolve as aplicações baseadas nas APIs. Assim como o UX é construído em torno da experiência do usuário, o DX gira em torno da experiência do desenvolvedor e todo o conceito tem como premissa a “empatia” ou compreender as necessidades e expectativas de outros desenvolvedores, ou seja, os desenvolvedores que vão experimentar sua API e espera-se a DX mais positiva possível.
Pilares que fortalecem a experiência
- Documentação de fácil entendimento, respeite o tempo do desenvolvedor, forneça exemplos de código nas linguagens de programação mais populares.
- Recursos devem responder a uma estrutura de dados JSON, código de status compreensível e, quando pertinente, deve apresentar o código e a mensagem de erro.
Principais terminologias
Resource é um objecto ou a representação de alguma coisa, que tem alguns dados associados a ele e pode haver um conjunto de métodos. Exemplo: Alunos, Funcionários, Animais são resources e delete, add, update são as operações a serem realizadas com estes resources.
Collections são os conjuntos de recursos. Exemplo: Companies é a collection do recurso Company.
Endpoint / URL (Uniform Resource Locator) é o caminho no qual o resource pode ser localizado e algumas ações podem ser realizadas sobre ele.
Como todos dizem, use apenas substantivos para os recursos
A URL deve conter somente recursos (substantivos), não ações ou verbos. É intuitivo usar substantivos no plural. Mas, acima de tudo, evite utilizar no singular. Seja consistente!
Utilize os métodos HTTP (GET, POST, DELETE, PUT), também chamados de verbos, para definir a ação a ser executada pelo recurso.
Lembre-se: o recurso deve ser sempre no plural e se quisermos acessar uma instância específica do recurso, podemos sempre passar o ID.
Resource | GET read | POST create | PUT update | DELETE |
/employees | Retorna a lista de colaboradores | Cria um novo colaborador | Atualização em massa dos colaboradores | Apaga todos colaboradores |
/employees/1 | Retorna um colaborador específico | Método não liberado (405) | Atualiza um colaborador específico | Apaga um colaborador específico |
Use HTTP Status Code
Existem mais de 70 HTTP Status Codes, seja simples, não existe um número máximo, mas indico não utilizar mais do que 12 HTTP Status Code no design da sua REST API.
As requisições RESTful devem sempre responder um HTTP Status Code, conforme a ação executada.
- 2xx – Success
- 4xx – Client Error
- 5xx – Server Error
Veja a lista com todos HTTP Status Codes: https://httpstatuses.com.
Inspire-se! Veja abaixo como os maiores players respondem as requisições HTTP:
Spotify | ||||||||||||
200 | 201 | 202 | 204 | 304 | 400 | 401 | 403 | 404 | 429 | 500 | 502 | 503 |
GitHub | ||||||||
200 | 400 | 422 | 301 | 302 | 304 | 307 | 401 | 403 |
Stipe | ||||||||||
200 | 400 | 401 | 402 | 404 | 409 | 429 | 500 | 502 | 503 | 504 |
Uber | ||||||||||
200 | 201 | 400 | 401 | 403 | 404 | 406 | 409 | 422 | 429 | 500 |
Salesforce | |||||||||||
200 | 201 | 204 | 300 | 304 | 400 | 401 | 403 | 404 | 405 | 415 | 500 |
Twilio | ||||||||||
200 | 201 | 400 | 401 | 404 | 405 | 429 | 500 | 304 | 503 | 204 |
- Referência: https://developer.spotify.com/web-api/user-guide/
- Referência: https://developer.github.com/v3/#client-errors
- Referência: https://stripe.com/docs/api#errors
- Referência: https://developer.uber.com/docs/riders/ride-requests/introduction
- Referência: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/errorcodes.htm
- Referência: https://www.twilio.com/docs/api/rest/request
Todos têm em comum: 400 Bad Request, 401 Unauthorized e 200 OK.
Versionamento
Quando pensar na evolução da API, o versionamento é uma das considerações mais importantes para o design. A partir do momento que a API entra no ambiente de produção, qualquer alteração no payload ou diretamente na assinatura pode implicar em uma quebra direta nos clientes que consomem os recursos da API.
Versionar a API deve ser uma prática mandatória para todo release.
É muito normal utilizar o número da versão diretamente na URL como /v1/employees ou /v2/employees.
Estratégias populares de versionamento
API | Versionamento | Exemplo |
Twilio | Data na URL | /2010-04-01/Accounts/{AccountSid}/Calls |
Atlassian | URL | context/rest/upm/latest ou /context/rest/upm/2 |
URL / Versão opcional | graph.facebook.com/v1.0/me | |
Youtube data API versioning | URL | googleapis.com/youtube/v3 |
Stripe | Custom Header | 2017-04-06 |
Filtro de busca
Uma busca simples pode ser implementada como um recurso para todos endpoints da API com parâmetro “q” para representar a consulta:
Recurso | Endpoint |
Colaboradores | /employees/?q=renato |
Clientes da Empresa 1 | /companies/1/customers/?q=adriana |
Ordenação complexa
Semelhante ao filtro para a busca, um tipo de parâmetro pode ser usado para descrever as regras de classificação. Acomodar exigências de classificação complexas, permitir que o parâmetro de classificação inclua uma lista de campos separados por vírgulas, cada um com um possível “negativo” ( – ) para implicar uma ordem de classificação descendente.
Vejamos alguns exemplos:
GET | /employees?sort=-created_at |
GET | /employees?sort=name,-created_at |
GET | /companies/1/employees/?sort=name,-birthdate,-created_at |
Palavras reservadas
As palavras reservadas podem ser utilizadas sempre após o recurso especificado
GET | FIRST | /employees/first | Retorna o primeiro elemento |
GET | LAST | /employees/last | Retorna o último elemento |
GET | COUNT | /companies/1/employees/count | Retorna o total de elementos |