...
Informações |
---|
title | Restrições para uma API RESTful |
---|
|
RESTful seria, então, a API que está de acordo com todas as restrições definidas por Roy.Os principais critérios para uma API ser RESTful são: - Uniform Interface;
- Resource-based: tenta lidar com recursos invés de métodos;
- Manipulation of resources through representations: recursos através de uma representação (JSON, XML, HTML.);
- Self-descriptive Messages: As respostas são auto descritivas, incluindo informação suficiente para que o cliente saiba como utilizá-las;
- HATEOAS: Padrão que sempre inclui links uteis junto as respostas de uma requisição.
- Stateless;Stateless -
- Não guarde nenhum tipo de estado referente a comunicação;
- Cacheable;
- Reduzir o número de chamadas feitas para o endpoint e também melhorar a latência de solicitações para a sua API.
- Client-Server;
- web/aplicação deve ser separada da solicitação/armazenamento dos dados.
- Layered system.
- O cliente nunca deve chamar diretamente o servidor da aplicação sem antes passar por um intermediador, no caso, pode ser um load balancer ou qualquer outra máquina que faça a interface com o(s) servidor(es)
Sem seguir todas estas restrições, sua API não será RESTful, será apenas mais uma implementação RPC em cima do protocolo HTTP. |
Deck of Cards |
---|
|
Card |
---|
label | URIs legíveis - Endpoints |
---|
| Padrão de nomenclatura http://{{host}}/api/{{agrupador}}/{{versão}}/{{resource}} - Dê preferência para o plural ao disponibilizar o resource. Utilize
/users ao invés de /user; - Dê preferência para URL's em minúsculo, evite
GET /Users , use GET /users; - Na API, utilizamos semantic versioning, um padrão que é dividido em major, minor e patch. Somente a Major Version é utilizada na URL. Por exemplo: V1 ou V2;
- Deve ser orientada a recursos representados por substantivos no plural. Não se deve orientar a verbos Get, Put, Post e Delete.
A raiz do resource deve retornar uma coleção. Por exemplo /users deve retornar um lista de usuários. Se desejar obter um resource especifico utilize o nível seguinte especificando seu identificador único. GET /users/2 . Não precisa ser o id do banco, poderia ser outro campo, desde que seja identificador único. Um usuário poderia ser o username. GET /users -> Retorna uma lista de usuáriosGET /users/bruno -> Retorna o usuário com username brunoPOST /users -> Cria um usuárioPUT /users/bruno -> Atualiza o usuário brunoPATCH /users/bruno -> Atualiza parcialmente o usuário brunoDELETE /users/bruno -> Remove o usuário bruno
Relacionamento filho - Se existir alguma tabela filho do resource, eles devem estar mapeados para o mesmo endpoint. Exemplo GET /users/bruno/claims -> Retorna uma lista de claims do usuário brunoGET /users/bruno/claims/6 -> Retorna o claims com Id 6POST /users/bruno/claims -> Cria uma claim para usuário brunoPUT /users/bruno/claims/6 -> Atualiza a claim 6 do usuário brunoPATCH /users/bruno/claims/6 -> Atualiza parcialmente a claim 6 do usuário brunoDELETE /users/bruno/claims/6 -> Remove a claim 6 do usuário bruno
Chave composta GET /sales/20_1020/rules -> Retorna uma lista de regras da coligada 20 e venda 1020GET /sales/20_1020/rules/6 -> Retorna uma a regra 6 da coligada 20 e venda 1020POST /sales/20_1020/rules -> Cria a regra 6 da coligada 20 e venda 1020PUT /sales/20_1020/rules/6 -> Atualiza a regra 6 da coligada 20 e venda 1020PATCH /sales/20_1020/rules/6 -> Atualiza parcialmente a regra 6 da coligada 20 e venda 1020DELETE /sales/20_1020/rules/6 -> Remove a regra 6 da coligada 20 e venda 1020
Exemplo [RoutePrefix("imb/v1/modalities")] [Route("{modalityId}/enterprises/{companyId}_{enterpriseId}")] [HttpGet] public List<ImbVendaModalidadeRegraEntity> GetTabelaPrecoModalidade(int modalityId, int companyId, int enterpriseId)
As propriedades devem ser sempre em minúsculo [JsonProperty("codcoligada")]
Evite adicionar na URI a operação a ser realizada no recursoOs recursos que uma aplicação gerencia podem ser manipulados de diversas maneiras, sendo para isso disponibilizada algumas operações para manipula-los, tais como: criar, listar, excluir, atualizar, etc. A manipulação dos recursos deve ser feita utilizando-se os métodos do protocolo HTTP, que inclusive é um dos princípios do REST que será discutido mais adiante. Portanto, evite definir URIs que contenham a operação a ser realizada em um recurso, tais como: GET/PUT/DELETE/PATCH /users/Cadastrar ;GET/PUT/DELETE/PATCH /users/bruno/Excluir ;GET/PUT/DELETE/PATCH /users/bruno/Atualizar .
Logo ações se fazem necessários no dia-a-dia. E é importante reforçar que não fere os padrões REST. POST /candidatos/{id}/candidatar -- Grava a aplicação de um candidato a uma vaga POST /candidatos/{id}/aprovar -- Aprova um candidato DELETE /candidatos/{id}/aprovar -- Cancela a aprovação POST /candidatos/{id}/reprovar -- Reprova o candidato DELETE /candidatos/{id}/reprovar -- Cancela a reprovação POST /candidatos/{id}/transferir -- Transfere o candidato para outra vaga DELETE /candidatos/{id}/transferir -- Cancela a transferência
Nesse formato a comunicação é clara. No backend o desenvolvedor não vai precisar criar if's ou switchs e traduzir a intenção do método "CRUD". O próprio endpoint comunica sua intenção. |
Card |
---|
| Os recursos gerenciados por uma aplicação, e identificados unicamente por meio de sua URI, geralmente podem ser manipulados de diversas maneiras. É possível criá-los, atualizá-los, excluí-los, dentre outras operações. Quando um cliente dispara uma requisição HTTP para um serviço, além da URI que identifica quais recursos ele pretende manipular, é necessário que ele também informe o tipo de manipulação que deseja realizar no recurso. É justamente aí que entra um outro conceito da Web, que são os métodos do protocolo HTTP. O protocolo HTTP possui diversos métodos, sendo que cada um possui uma semântica distinta, e devem ser utilizados para indicar o tipo de manipulação a ser realizada em um determinado recurso. Vejamos agora os principais métodos do protocolo HTTP e o cenário de utilização de cada um deles: GET: Obter os dados de um recurso. POST: Criar um novo recurso. PUT: Substituir os dados de um determinado recurso. PATCH: Atualizar parcialmente um determinado recurso. DELETE: Excluir um determinado recurso. HEAD: Similar ao GET, mas utilizado apenas para se obter os cabeçalhos de resposta, sem os dados em si. OPTIONS: Obter quais manipulações podem ser realizadas em um determinado recurso.
Geralmente as aplicações apenas utilizam os métodos GET, POST, PUT e DELETE, mas se fizer sentido em sua aplicação utilizar algum dos outros métodos, não há nenhum problema nisso.
HTTP Method | Idempotente | Safe |
---|
OPTIONS | | | GET | | | HEAD | | | PUT | | | POST | | | DELETE | | | PATCH | | |
Idempotente significa que o endpoint pode ser chamado várias vezes sem resultados diferentes. Não importa se o método é chamado apenas uma ou dez vezes. O resultado deve sempre o mesmo. Isso se aplica apenas ao resultado, não ao próprio recurso. Safe são métodos Read-only. Isso significa que são seguros e não importa quantas vezes chamar, ele não irá alterar o estado do resource.
|
Card |
---|
| Quando o servidor recebe uma solicitação HTTP, o cliente deve saber o resultado da ação. Se houve sucesso ou falhou. Os códigos de status HTTP são vários códigos padronizados, com várias explicações em vários cenários. O servidor sempre deve retornar o código de status correto. A seguir estão as categorias dos códigos HTTP: - 2xx - Status de sucesso
- 3xx - Categoria de redirecionamento
- 4xx - Erro no Cliente
- 5xx - Erro no server
2xx - SucessoAbaixo uma tabela de quando utilizar cada um dos Status Code. - 200 Ok - Padrão que representa sucesso. Resposta padrão para GET, quando há resultados.
- 201 Created - Indica que um recurso foi criado. Utilize para a resposta do POST. E também retorne o Header
Location indicando o GET dessa informação. - 204 No Content - Representa que a request foi processada com sucesso, mas não há conteúdo para ser retornado. Utilize para PUT, PATCH e DELETE. E também para situações em que o GET não retornou resultados.
- 202 Accepted - Indica que o servidor aceitou a request. Esse é um ótimo Status para processos assíncronos. Por exemplo um cenário onde o usuário faz upload de uma planilha que será processada em background.
3xx - RedirectComo desenvolvedor, não consigo visualizar cenários em que será utilizado o redirect a partir de uma API RESTFul. Em geral o 302 é bastante utilizado em desenvolvimento Frontend, como Razor. E o 301 Moved Permanently é utilizado por sysadmins, para indicar que um site foi permanentemente redirecionado para um novo endereço. 4xx - Client errorIndica que o client cometeu uma falha na requisição. - 400 Bad Request - A solicitação não foi processada, pois o servidor não entendeu o que o cliente está solicitando.
- 401 Unauthorized - Indica que o client não está autenticado e não tem autorização para acessar o recurso.
- 403 Forbidden - Indica que o Client está autenticado e a requisição é válida. Porém o client não tem permissão de acesso naquele recurso.
- 404 Not Found - indica que o recurso não foi localizado.
- 422 - Unprocessable Entity - A validação não pode ser processada por que algum valor inválido foi enviado na requisição.
5xx - Erros no servidorOs status 5xx há dois que merecem destaque. É o erro 500, houve uma falha no servidor e não conseguiu processar a requisição. E o erro 503 que vai botar o pessoal de infra para correr. Indica que o serviço está indisponível. Status comum quando o Webserver sobrecarrega de requisições e não consegue mais processar nenhuma requisição. O 503 é comum em cenários de ataques DDoS.
|
Card |
---|
| O Open Api, anteriormente conhecido como Swagger, é hoje o padrão mais utilizado para documentar API's. No ASP.NET Core é muito fácil configurar. Ele disponibiliza mecanismos para testar sua API no Browser.
|
Card |
---|
label | Implementado APIs TCGI |
---|
| Incluir Página |
---|
| Implementando APIs TCGI |
---|
| Implementando APIs TCGI |
---|
|
|
Card |
---|
| Exemplos de uso de api de dataserver
Verbo: Get Ação: Com filtro URI: http://localhost:8051/rmsrestdataserver/rest/ImbPVIClienteData?filter= ["nome like :nome and CPFCNPJ = :cpf", "%teste%", "044.266.846-50"]
Verbo: Get Ação: Primary Key URI: http://localhost:8051/rmsrestdataserver/rest/ImbPVIClienteData/2
Verbo: Get Ação: Primary Key Composta URI: http://localhost:8051/rmsrestdataserver/rest/FinCFODataBR/1$_$C100338
Verbo: POST Ação: Somente para inserir URI: http://localhost:8051/rmsrestdataserver/rest/ImbPVIClienteData [ { "ID":-1, "NOME": "teste api 5", "CPFCNPJ": "044.266.846-50", "TIPO": 0, "TIPOPESSOA": 0, "DATAHORACADASTRO":"2022-10-27T11:09:58.52-03:00", "INSCRICAOESTADUAL":" ", "CONJUGE_PROFISSAO_ID": 1, "LEAD": 0, "LEAD_POTENCIAL": 0 } ]
Verbo: DELETE Ação: Deletar o registro com a primary key URI: http://localhost:8051/rmsrestdataserver/rest/ImbPVIClienteData/2
Verbo: PUT Ação: Atualiza todos os registros, a lib faz o merge de todos os campos URI: http://localhost:8051/rmsrestdataserver/rest/ImbPVIClienteData/2
{ "ID": 2, "NOME": "teste api PUT", "CPFCNPJ": "044.266.846-50", "TIPO": 0, "TIPOPESSOA": 0, "DATAHORACADASTRO":"2022-10-27T11:09:58.52-03:00", "INSCRICAOESTADUAL":" ", "CONJUGE_PROFISSAO_ID": 1, "LEAD": 0, "LEAD_POTENCIAL": 0 }
Verbo: PATCH Ação: Atualiza alguns campos dos registros, a lib faz o merge somente dos campos enviados URI: http://localhost:8051/rmsrestdataserver/rest/ImbPVIClienteData/2 { "NOME": "teste api patch" }
Demais exemplos segue a documentação da lib: Serviços RESTful de DataServer no RM |
|
Autenticação
Garantir a segurança dos dados também faz parte do desing de uma API, hoje o principal modelo utilizado pela comunidade é o Oauth 2.0, este é um padrão de autenticação, que foi construído para preservar os dados sensíveis de um usuário, minha recomendação seria sempre que possível utiliza-lo, porem caso não seja possível, não deixe sua API sem autenticação, no mínimo utilize uma autenticação do tipo basic, onde geralmente é criado um token em base64 a partir de um usuário e senha.
A utilização de Tokens de acesso, que são gerados pelo serviço REST devem ser armazenados pelos clientes, via cookies ou HTML 5 Web Storage, devendo também ser enviados pelos clientes a cada nova requisição ao serviço.
Outras tecnologias e padrões para se trabalhar com Tokens:
- OAUTH;
- JWT (JSON Web Token);
- Keycloack.
Stateless
Garanta que sua API não guarde nenhum tipo de estado referente a comunicação, toda requisição deve ser inteligente o suficiente para se resolver, sem armazenar quaisquer dados de seção.
Negociação de conteúdo
Apesar do ideal ser trafegar apenas JSON, caso sua API trafegue outros tipos de dados, por exemplo XML, utilize as chaves Accept e Content-Type do protocolo HTTP para detalhar todas as possibilidades
Paginação
Em requisições GET que retornem listas, devolva somente o necessário, pagine sua requisição, desta forma todos ganham, pois será trafegado somente o necessário, melhorando a experiência do usuário final.
Ordenação
Otimize suas requisições, facilite ainda mais a vida de seus clientes, permita que sua Api, ordene sua resposta, desta forma o cliente pode não precisar realizar nenhum tipo de tratamento no dado.
Respostas Parciais
Otimize ainda mais suas requisições GET, permita seus clientes recuperarem somente os campos que realmente necessitam, desta forma de ponta a ponta serão trafegado apenas os dados necessários.
Hateoas
Hateoas representa o termo Hypermedia as the engine of application State (Hipermídia como o mecanismo do estado do aplicativo), é um padrão que sempre inclui links uteis junto as respostas de uma requisição
Os principais benefícios de seguir essa abordagem são:
- As aplicações clients conhecem facilmente o limite e próximos passos de cada domínio
- As aplicações clients podem recuperar seus paths dinamicamente sem a necessidade de colocar-los fixo no código
- Os desenvolvedores da API podem alterar o esquema de paths sem quebrar as aplicações clients
<acao><rel>self</rel><uri>http://servicorest.com.br/pedidos/1459</uri><method>GET</method></acao>
Open Documentation
Alem de seguir as melhores práticas, faça ainda mais que isso, utilize frameworks como o Swagger, que é um framework open source que apoia o desenvolvedor no desenho, documentação e especificação de suas Api's.
Conclusão
Se você leu atentamente todos os itens citados acima, você ja tem a total certeza que para construir uma API Rest de alta qualidade, não basta apenas conhecer uma linguagem de desenvolvimento, é preciso conhecer muito bem o protocolo HTTP e um conjunto de padrões que com certeza elevam o nível de sua API.
Fontes:
Serviços RESTful de DataServer no RM
https://api.totvs.com.br/guia
...
https://wssilva-willian.medium.com/design-de-api-rest-9807a5b16c9f
https://imasters.com.br/desenvolvimento/definicao-restricoes-e-beneficios-modelo-de-arquitetura-rest
https://martinfowler.com/articles/richardsonMaturityModel.html
https://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/api-gateway-caching.html