Nesse artigo iremos apresentar as melhores práticas arquitetando uma api restful, exemplos de APIs reais em diferentes linguagens de programação, preços para execução, e muito mais!
- Uma breve introdução ao REST.
- Uma breve introdução ao HTTP.
- Conceitos importantes para uma API RESTful.
- Melhores práticas para o Design de uma API RESTful.
- Linguagens de programação e plataformas para publicar as APIs
- Agradecimentos
1. Uma breve introdução ao REST
As APIs de serviços web têm crescido significativamente, permitindo que empresas expandam seus negócios através de integrações com diversos serviços. Como resultado este crescimento impacta tanto os aspectos comerciais quanto técnicos. Assim muitas dessas APIs são desenvolvidas com base no conceito de REST (Representational State Transfer), que define um conjunto de princípios arquiteturais para a comunicação entre cliente e servidor. REST foi concebido por Roy Fielding em sua Tese de Doutorado. Fielding também é conhecido por ser um dos autores do protocolo HTTP. Entretanto é importante destacar que REST não está intrinsicamente ligado ao HTTP, apesar de ser amplamente utilizado em conjunto com este protocolo atualmente.
O REST se baseia em diversos princípios, tais como:
- Baseia-se no estilo arquitetural cliente e servidor, permitindo portanto a portabilidade da interface do usuário em múltiplas plataformas e auxilia na escalabilidade. Um cliente realiza requisições para um servidor, o qual processa os dados, e fornece uma resposta ao cliente.
- Stateless (ausência de estado), pois cada requisição do cliente ao servidor deve conter todas as informações necessárias para que o servidor entenda a requisição.
- Possibilidade de suporte a cache para otimizar a eficiência da rede.
- Interface uniforme de acesso por parte do servidor para que diferentes clientes interajam de forma facilitada com o servidor.
1.1 Compreendendo a terminologia
Para compreender o REST enquanto arquitetando uma api restful, também temos que compreender os seguintes elementos:
- Recurso: O Alvo/Objetivo conceitual pretendido (por exemplo: um documento, imagem, coleção de outros recursos, etc).
- Identificador de recurso: Recursos devem estar presentes e serem acessíveis de alguma maneira (por exemplo: URL, URN, etc).
- Representação: Define como o recurso é representado (por exemplo: imagem PNG, JPEG, um documento HTML, CSS, etc). Conta também com meta dados da representação, como ultima data de modificação, etc.
- Dados de controle: Dados a fins de controle de cache, etc.
2. Uma breve introdução ao HTTP
Em seguida iremos abordar o protoclo HTTP. O protocolo HTTP é amplamente utilizado em conjunto com o REST. No HTTP, a comunicação se da entre o cliente e o servidor através de requisições e respostas. A imagem a seguir apresenta uma requisição feita de um navegador para um servidor Web.
Note os seguintes elementos de uma requisição:
2.1 Método
Os métodos (GET, POST, PUT, DELETE, PATCH,etc ) permitem manipular os recursos em servidores web. São de extrema importancia enquanto arquitetando uma api restful.
- GET: É utilizado para operações de leitura de recursos (por exemplo, listagem de clientes).
- DELETE: É utilizado para operações de remoção de recursos (por exemplo, exclusão de clientes).
- POST: Geralmente utilizado para criar um novo recurso (por exemplo, criação de clientes).
- PUT: Geralmente utilizado para atualização de um recurso (por exemplo, alteração de dados de cliente).
*ATENÇÃO! Quando não sabemos a localização de um novo recurso, devemos utilizar POST, e quando sabemos a localização de um recurso, o método PUT! A princípio na definição do HTTP não há nada que associe POST a inserir e PUT a atualizar, embora o mesmo seja utilizado para estes fins normalmente.
2.2 Endereço do recurso
Para realizar a manipulação de dados é necessário saber onde está localizado o endereço do recurso. Em uma analogia, pense em uma rua: uma pessoa vai até um determinado endereço a fim de realizar alguma operação (método).
2.3 Versão do protocolo HTTP.
Indica a versão do protocolo HTTP que está sendo utilizada na comunicação. Pode ser utilizado HTTP 1.1, 2.0, etc.
2.4 Cabeçalhos
Estrutura de chave e valor. Incluem o host, tamanho do conteúdo, formatos aceitos, linguagens aceitas, etc.
2.5 Corpo da requisição.
Podemos utilizar diversos formatos:
- None: Não há um corpo para a requisição.
- Form-data: São enviados a partir de estrutura de chave e valor. Por exemplo, a chave seria “Usuario” enquanto o valor seria “Usuario De Teste”, visto que cada par é uma parte da mensagem e tem seu próprio cabeçalho.
- Xwww-form-urlencoded: Separa chave e valor em chaves. Por exemplo: nome=teste&idade=25
- Raw: Formato “cru”, pode ser enviado texto, JSON, XML, HTML, JavaScript, etc.
- Binary: Utilizado para recursos em formato binário. Por exemplo: Enviar arquivos PDF, etc.
Portanto a mensagem é enviada do cliente para o servidor, o servidor a processa e envia de volta uma resposta ao cliente, de maneira semelhante a da imagem abaixo.
Podemos notar novamente a versão do protocolo (HTTP/1.1), cabeçalhos de resposta, corpo de resposta (pode ser HTML, JSON, XML,etc). Porém há um elemento novo, o Status da Resposta com um descritivo.
2.6 Código de status da resposta
Indica se a requisição foi concluída de maneira correta. Existem cinco classificações de respostas, as de informação, sucesso, redirecionamento, erro do cliente e erro do servidor. São essenciais enquanto arquitetando uma api restful.
- De 100 a 199: Respostas de informação. Por exemplo: 102 PROCESSING — diz que o servidor já recebeu a requisição mas nenhuma resposta está disponível no momento.
- De 200 a 299: Respostas de sucesso. Por exemplo: 200 OK — Requisição bem sucedida (por exemplo em listagens). 201 CREATED — Novo recurso criado (utilizado em requisições POST por exemplo).
- De 300 a 399: Respostas de redirecionamento. Por exemplo: 302 FOUND — Significa que a URI do recurso foi mudada temporariamente (por exemplo em uma troca de página).
- De 400 a 499: Respostas de erro do cliente. Por exemplo: 404 NOT FOUND — Recurso não encontrado. 401 UNAUTHORIZED- Cliente deve se autenticar. 400 BAD REQUEST. — Servidor não entendeu a requisição dado alguma sintaxe inválida (dados inválidos por exemplo).
- Acima de 500: Respostas de erro no servidor. Por exemplo: 500 INTERNAL SERVER ERROR — Servidor encontrou uma situação que ele não sabe lidar (por exemplo: falta de memória, erro de conexão com banco de dados, etc). 503 SERVICE UNAVAILABLE — Servidor não está pronto para manipular a requisição, o serviço está indisponível.
3. Conceitos importantes enquanto arquitetando uma api restful
Posteriormente compreendemos um pouco sobre o protocolo HTTP. Em seguida iremos abordar um pouco sobre diversos conceitos importantes no mundo REST.
3.1 Modelando pensando em Idempotência e segurança
Antes de iniciar a modelagem de uma API Restful, é necessário sabermos alguns conceitos sobre idempotência e segurança. Ambos estes conceitos estão relacionados diretamente aos métodos HTTP. Note que a modelagem de forma correta destes conceitos é de grande importância, pois, alem de prevenir possíveis problemas e efeitos indesejados, acaba gerando um mecanismo padrão a ser seguido por toda a equipe de desenvolvimento.
3.1.1 Métodos seguros
Um método é tido como seguro se ele for utilizado apenas para operações de leitura, tais como o GET, HEAD e OPTIONS. Não se espera que seja feito qualquer tipo de alteração no estado do servidor enquanto é realizado uma requisição a estes métodos.
De acordo com a definição da RFC 2616:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered “safe”. This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested. RFC 2616 Fielding, et al.
3.1.2 Métodos Idempotentes
De acordo com a definição original definida na RFC 7231:
A request method is considered “idempotent” if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. RFC 7231 Seção 4.2.2. Fielding & Reschke.
Portanto um método é considerado idempotente se os efeitos colaterais de uma ou mais requisições idênticas forem iguais a uma única requisição.
Idempotência se refere ao estado do sistema depois que a requisição tenha sido completada. Isto é, caso você faça uma operação que envolve o método DELETE para remover algo, após a remoção, o recurso não existe mais no servidor. Agora, independente da quantidade de vezes que você executar a mesma requisição DELETE, o servidor continuará com mesmo estado. Logo, DELETE é um método idempotente. O mesmo conceito pode se aplicar aos métodos GET, PUT, HEAD e OPTIONS, seguindo a linha de raciocínio do método DELETE.
Note que durante essas requisições, o servidor pode responder de maneira diferente, porém, o estado do servidor continua o mesmo.
3.2 Modelando pensando no Modelo de Maturidade de Richardson.
É muito comum enquanto arquitetando uma api restful encontrar definições do modelo de maturidade de Richardson sendo algo como: Os passos para se alcançar a glória do REST. O modelo de Richardson basicamente divide o REST em três passos que introduzem recursos, métodos HTTP e Hypermedia.
A divisão se dá por quatro níveis na realidade. Nível 0, 1, 2 e 3.
3.2.1 O nível 0 — Pantano
No nível 0, é o conhecido pântano, onde não se utiliza múltiplos endereços para recursos, não há diferenciação entre os métodos HTTP, Status do código de resposta, nem nada disso. O que existe basicamente é uma chamada remota.
Um exemplo disso é realizar requisições a um único endereço, e dependendo do corpo da mensagem que for enviado, o servidor realizará uma ação específica. É extremamente difícil de ser mantido. Isso é o que você deseja fugir enquanto arquitetando uma api restful.
3.2.2 O nível 1 — Recursos
No nível 1, as coisas começam a ficar mais divididas. Se começa a utilizar o conceito de recursos, então, ao invés de enviar todas as requisições a um único endereço, agora chamamos endereços individuais.
Um exemplo, é existirem vários endpoints ao invés de um único endpoint (como no nível 1).
Isso acaba gerando uma melhor divisão de conceitos, o que facilita a gestão dos recursos.
3.2.3 O nível 2 — Métodos e Status HTTP
Para estar neste nível, o pré-requisito é o nível 1. Já para estar no nível 2, é necessário utilizar os métodos HTTP e os códigos de status de maneira correta. Utilizar GET para obter dados, DELETE para remover, POST quando não se sabe o endereço do recurso (tipicamente adicionar), PUT quando se sabe o endereço do recurso (tipicamente alterar).
Um exemplo disso, é o seguinte caso: Imagine enviar uma requisição para o nosso antigo serviço http://servidor.com/clientes. Digamos que iremos utilizar uma POST para adicionar um novo cliente. Então no final da requisição, o código de retorno deve ser 201 — CREATED. Ao consultar um recurso que não existe, retornar 404 — NOT FOUND. Em casos de falta de autenticação, utilizar 401 — UNAUTHORIZED. Se não se pode realizar uma ação especifica devido a algumas regras, 403 — FORBIDDEN.
3.2.4 O nível 3 — Controles de Hypermedia
Aqui o pré-requisito é já estar no nível 2 de maturidade. O nível 3 é o chamado “A glória do REST”.
No nível 3, introduzimos os controles de hypermedia. Você já deve ter ouvido falar de HATEOS (Hypertext As The Engine Of Application State). É basicamente a capacidade de “navegar” de uma API para outra através de recursos de Hyper Media.
Assim como citado por Martin Fowler, este seria um possível retorno de uma API nível 3:
GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1
Host: royalhope.nhs.uk
HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id = “1234” doctor = “mjones” start = “1400” end = “1450”>
<link rel = “/linkrels/slot/book”
uri = “/slots/1234”/>
</slot>
<slot id = “5678” doctor = “mjones” start = “1600” end = “1650”>
<link rel = “/linkrels/slot/book”
uri = “/slots/5678”/>
</slot>
</openSlotList>
Note a capacidade de navegar entre APIs facilmente. Por exemplo, uma API de listagem de clientes poderia retorna Links para APIs de pagamentos específicas para cada cliente.
Por definição, na tese de Roy Fielding, para uma API ser considerada REST ela deve estar no nível 3. Porém, no dia a dia das empresas nem sempre uma API RESTful necessita estar no nível 3. Praticar algo em torno do nível 2 e nível 3 já está de bom tamanho!
4. Melhores práticas enquanto arquitetando uma api restful
Ao realizar o design de uma API RESTful, devemos entender que ela será um serviço exposto para um desenvolvedor, então devemos colocar esforços em tornar nossa API apresentável. Vamos apresentar algumas boas práticas no mundo das APIs.
4.1 Use recursos corretamente
Um recurso deve ser um substantivo, e não um verbo! Por exemplo, ao envés de:
- GET /listar_clientes — Errado
- GET /clientes — Certo
Algumas pessoas preferem utilizar o substantivo no plural, outras no singular. Isso não importa, o importante é que você deve seguir um padrão em todas as suas APIs, então, se modelar um recurso semelhante a GET /clientes, sempre utilize plural. O importante é a padronização. Escolha se irá utilizar substantivos no plural ou singular e aplique em seu projeto de forma consistente.
Outra observação é que recursos devem ser descritivos, fáceis de entender, e para isso, é recomendado utilizar o nível 2 ou nível 3 de maturidade de Richardson. Por exemplo:
- GET /clientes — Lista os clientes.
- GET /clientes/1 — Obtém os dados do cliente 1.
- POST /clientes — Cria um novo cliente.
- PUT /clientes/1 — Altera o cliente 1.
- DELETE /clientes/1 — Remove o cliente 1.
- PATCH /clientes/1 — Atualiza parcialmente o cliente 1.
Também podemos realizar relações de recursos, tais como:
- GET /clientes/1/parceiros — Lista os parceiros do cliente 1.
- GET /clientes/1/parceiros/1 — Lista o parceiro 1 do cliente 1.
Note que devemos tomar cuidado com a extensão do recurso. Utilize normalmente no máximo um encadeamento de 3–4 recursos no máximo. Isso para facilitar a compreensão.
4.2 Documente sua API
Algumas pessoas dizem que uma API é tão boa quanto sua documentação. A documentação precisa ser fácil de encontrar, compreensível ao desenvolvedor, fácil de testar e informar o seu proposito específico.
Um bom exemplo a ser seguido é a API da Marvel (acesso a ela nas referências), dado que ela possui uma lista das APIs, o método, recurso e uma descrição simples do que ela faz. Ao clicar em uma API em específico, temos uma descrição, os dados que a API retorna e possíveis códigos de status que o servidor pode retornar.
Também é muito interessante fornecer ao desenvolvedor um ambiente em que ele possa simular a API. Em casos de API muito complexas, como por exemplo, emissão de uma nota fiscal, lidar com dados bancários, etc, é bom termos um manual de referência muito bem documentados e atualizados para facilitar a vida do desenvolvedor.
4.3 Versione sua API e dê significados a ela
É uma boa prática sempre versionar sua API. Normalmente se utiliza o versionamento na URI do recurso:
- GET /v1/clientes
- POST /v1/clientes
Também podemos criar uma nomenclatura própria dependendo da demanda interna da API. Por exemplo, em um conjunto de APIs que estarão disponíveis para o público em geral, podemos utilizar a seguinte nomeação:
- GET /v1/public/characters
- GET/v1/public/characters/1
Este é o modelo utilizado pela API da Marvel, o qual é extremamente descritivo e intuitivo.
4.4 Utilize JSON onde conseguir para a resposta de suas APIs
Sabemos que em alguns casos específicos precisamos lidar com XML. Porém, onde for possível, realize a resposta de suas APIs em formato JSON. Além de ser um formato amplamente utilizado na Web, os arquivos JSON usam 30% menos banda do que arquivos XML.
Nos campos do JSON, existem desenvolvedores que usam Camel Case (camelCase) e snake case (snake_case). Não existe certo ou errado, porém, novamente, é importante seguir um padrão e manter a consistência. Uma dica interessante apresentada no artigo de Vinay Shani (pode ser visto em referencias) é utilizar a convenção da linguagem que você está usando. Exemplo: Se estiver em ambiente Java, camelCase, em Python, snake_case.
4.5 Padronize a entrada de suas APIs
Também é interessante padronizar o mecanismo de entrada de suas APIs. Antes de mais nada, é importante verificar em quais casos você utilizará Form Param, Form URL Encoded, RAW, Binary, etc. Assim sendo, mantenha a consistência. O suporte à serialização pode tornar interessante a transferência de mensagens em formato JSON. Além disso, em várias linguagens existem diversos mecanismos e bibliotecas para serializar e desserializar JSON ou XML, caso necessário.
4.6 Sempre use HTTPS
As pessoas podem acessar suas APIs de diversos locais (shoppings, em casa, aeroportos, bancos, restaurantes, etc). Devemos tomar cuidado, pois nunca se sabe se não há ninguém interceptando as mensagens. Não deixe as pessoas acessaram sua API sem o uso de HTTPS.
4.7 Para alguns tipos de requisição, utilize Query Params.
Você já deve ter visto algo como o seguinte:
- GET /clientes?ativo=true
São os chamados Query Params. É interessante utilizar este tipo de parâmetro em situações de busca, filtro, ordenação, status, paginação, etc.
4.8 Cache e Autenticação
Para dados que não mudam frequentemente e não são sensíveis a erro, é interessante a utilização de caches para otimizar a performance de sua API.
Mecanismos de autenticação são comuns na maior parte das APIs hoje em dia. Temos diversas formas de realizar autenticação, como por exemplo:
- Sem autorização.
- Bearer Token.
- Basic Auth.
- Digest Auth.
- OAuth 1.0.
- OAuth 2.0
- Hawk Authentication.
- AWS Signature.
- Dentre outros mecanismos.
É importante antes de tudo verificar o nível de autenticação que você deseja em sua API. Para acessar serviços do governo Brasileiro (tais como dados fiscais), por exemplo, é necessário utilizar certificados digitais. Já em casos de Login de usuário em sistemas que não precisam de mecanismos elevados de segurança talvez seja mais interessante utilizar JWT. Note que dependendo do tipo de API, a legislação pode influenciar na forma de autenticação que você irá escolher.
4.9 Faça o uso de Logs em sua api restful
Logs em excesso podem degradar a performance de um sistema. Porém, quando bem usados, criam mecanismos que auxiliam muito no processo de debug. Dentre algumas práticas:
- Tenha uma estrutura consistente de Logs.
- Use níveis de severidade de um Log (Debug, Info, Warn, Error, etc).
- Forneça uma boa descrição para o Log, indicando todo o contexto do problema.
- Demonstre dados de contexto do erro.
- Utilize uma estrutura de data e hora.
- Realize log de exceções e alertas.
- Tenha um mecanismo centralizado que lhe permita acessar seus Logs de forma fácil e rápida.
- Em logs, qualidade é mais importante que quantidade.
- Verifique algumas ferramentas para lhe auxiliar no processo de Log. Por exemplo: Log4j, Log4net, etc.
4.10 Tenha métricas sobre suas APIs
4.11 Forneça mensagens de retorno descritivas
Vamos supor que você esteja tentando realizar a seguinte requisição:
- POST /clientes
Porém lhe é retornado o seguinte:
{
“codigo”: 1,
“mensagem”: “Algo deu errado”,
“description”: “Aconteceram alguns erros ao adicionar este cliente”
}
A interface deve fazer validações para auxiliar o usuário e tornar tudo mais intuitivo e dinâmico, porém é importante que sua API tenha validações a fim de promover consistência em seus dados. Um retorno mais interessante seria o seguinte:
{
“codigo”: 1,
“mensagem”: “Erro de validação”,
“erros”: [{
“codigo”: 100,
“campo”: “email”,
“mensagem”: “E-mail deve ter no máximo 120 caracteres”
},
{
“codigo”: 101,
“campo”: “nome”,
“mensagem”: “Nome deve ter no máximo 100 caracteres”
},
{
“codigo”: 102,
“campo”: “senha”,
“mensagem”: “Senha não pode ser vazia”
}
]
}
Assim, você garante que independente de quem estiver realizando a requisição (sistema, site, aplicativo, terceiros), as informações serão consistentes.
4.12 Divida sua API restful em camadas se necessário
Ao estruturar uma API, é interessante dividi-la em camadas (tudo depende da necessidade, aqui demonstraremos um exemplo de divisão em camadas). Assim cada camada terá sua responsabilidade específica. Um modelo interessante a se seguir, é o seguinte:
- Camada de persistência de dados: Lida com o banco de dados de nossa aplicação.
- Camada de serviço/negócios: Contem as lógicas de negócio de nossa aplicação.
- Camada de recurso: Realiza a exposição dos recursos.
4.13 Faça paginação em quantidade de dados elevadas
No caso de uma lista com uma grande quantidade de dados, uma boa prática é a realização de paginação enquanto arquitetando uma api restful. Retornar 100.000 clientes em um único JSON acaba não sendo uma solução muito interessante. Na paginação, podemos passar alguns dados a nossa API:
- Quantidade de registros a ser retornada.
- Página que desejamos.
- Ordenação.
No retorno, é interessante mostrar a página atual e a quantidade total de páginas totais se possível. Exemplo de requisição:
- GET /clientes?page=1&pageSize=10&sort=nome
Também é interessante retornar no corpo de resposta a página anterior e a próxima página (se houver em ambos os casos) e outros dados úteis. Exemplo de resposta:
{
“dados” : [
{ dado1 },
{ dado2 },
…
],
“paginacao”: {
“paginaAtual”: 2,
“quantidadeDeItens”: 10,
“anterior”: “/clientes?pagina=1&pageSize=10”,
“proximo”: “/clientes?pagina=3&pageSize=10”
}
}
5. Linguagens de programação e plataformas para publicar as APIs restful
Agora que já sabemos as melhores práticas para o desenvolvimento das APIs, em seguida iremos escolher uma linguagem de programação para desenvolver as APIs e um ambiente para publica-las.
5.1 — Entendendo Contexto e requisitos do sistema
É necessário entendermos que tipo de problema estamos tentando resolver, quais os requisitos funcionais e não funcionais que devemos satisfazer, compreender o domínio e contexto do problema em que iremos atuar, o que o usuário e ou cliente espera do sistema e como o mesmo agregará valor. Devemos entender enquanto arquitetando uma api restful aspectos de qualidade que o sistema deve fornecer, como: disponibilidade, segurança, desempenho, usabilidade, portabilidade, etc. Desse modo poderemos nos situar melhor na escolha de uma tecnologia.
5.2 — Critérios de escolha da linguagem
Enquanto arquitetando uma api restful, ao escolher uma linguagem, é interessante analisar uma série de fatores:
- Documentação fornecida.
- Força da comunidade.
- Conhecimento prévio.
- Bibliotecas e componentes fornecidos.
- Adoção pelo mercado.
- Arquitetura da linguagem (Java, JavaScript, C#, Erlang, Elixir, C++, Rust, Go, Python, PHP, Groovy, Scala, Perl, etc) e do ambiente em que ela executa.
- Compatibilidade entre o que a linguagem fornece e o seu sistema tenta resolver.
- Estabilidade da linguagem.
- Cultura da organização.
- Facilidades que cada linguagem fornece.
- Desempenho da linguagem.
- Bugs conhecidos na linguagem.
- Facilidade de desenvolvimento.
- Ambiente necessário para a execução da linguagem escolhida.
- Dentre outros critérios.
Assim teremos uma boa noção de cada linguagem e idealmente uma boa quantidade de alternativas. Dada as alternativas, deve ser escolhida a linguagem que melhor resolve o problema dados os critérios acima. Sempre é importante analisar o custo/benefício que a linguagem fornecerá em seu projeto.
5.3 — Exemplos de APIs em diferentes linguagens de programação
Abaixo há uma série de linguagens que podem ser utilizadas para desenvolver APIs, inclusive, com exemplos em código de como ficam as APIs:
- Java — Spring.
- Java — Jersey
- C# — .NET Core.
- JavaScript — Node.js.
- Python — Flask.
- Elixir — Maru.
- PHP — Laravel.
- Rust — Rocket.
- Go
- Dart
5.4 —Escolhendo uma “plataforma” para a execução da API restful
Antes de realizar a hospedagem da API, precisamos entender alguns conceitos:
- IAAS — Infrastructure as a Service: A empresa contrata capacidade de hardware, memória, armazenamento, processamento, etc. Portanto esse modelo oferece um maior nível de flexibilidade e controle do gerenciamento sobre seus recursos, sendo geralmente o que os desenvolvedores mais comumente estão acostumados.
- PAAS — Platform as a Service: A empresa contrata um ambiente completo de desenvolvimento onde se cria, modifica e otimiza software. Portanto esse modelo é focado em se preocupar mais com a programação do que com o gerenciamento da infraestrutura.
- SAAS — Software as a Service: É basicamente o software como um serviço, como Facebook, Twitter, Skype, etc. Portanto nessa categoria se oferece um produto final ao usuário.
Ademais, uma boa documentação a ser acessada sobre os tipos de computação em nuvem é a da Amazon Web Services, que descreve outros detalhes como implantação em nuvem, híbrida e local.
5.5 —Provedores de nuvem
Abordado estes conceitos, iremos verificar alguns provedores de computação em nuvem:
- Amazon Web Services.
- Google Cloud Platform.
- IBM Cloud.
- Oracle Cloud.
- Alibaba Cloud.
- Dentre diversas outras.
Você deve levar essas pesquisas em consideração enquanto arquitetando uma api restful. Segue abaixo uma pesquisa realizada pela ZDNET em 2019:
Ao utilizar a ferramenta do Google Trends, podemos visualizar os seguintes dados baseados nos últimos 12 meses (visto que pesquisa feita dia 03/11/2019):
Também podemos visualizar estes dados por regiões no brasil.
Devemos enquanto arquitetando uma api restful escolher uma plataforma fazer um estudo prévio, contendo alguns dos seguintes aspectos :
- Recursos que cada uma das soluções oferece.
- Serviços que utilizaremos.
- Custo para a execução.
- Quantidade de documentação presente em cada solução.
- Nível de suporte e auxilio que a plataforma fornece.
- Quantidade de conteúdo disponível.
- Comunidade que utiliza a plataforma.
- Dentre outros.
5.6 — Perguntas a serem feitas
Geralmente, é fornecido um período de teste de 12 meses para que você possa se acostumar e familiarizar com a plataforma. No entanto, note que existem limitações neste período de teste, que, caso excedidas, podem gerar custos. Feito um estudo mais detalhado de cada solução, podemos nos perguntar:
- Primeiramente, utilizarei um SGBD relacional (MySQL, PostgreSQL, SQL Server, etc.) ou uma solução NoSQL (MongoDB, DynamoDB, etc.)?
- Além disso, utilizarei algum mecanismo de armazenamento em memória como o Redis ou Memcached?
- Assim sendo, utilizarei algum produto de API Gateway fornecido pelas soluções (API Gateway da AWS, API Gee da Google Cloud, etc.)?
- Em seguida, a plataforma suporta a hospedagem para a linguagem de programação e plataformas que estou utilizando?
- Utilizarei uma arquitetura monolítica ou de microserviços? Devo utilizar computação serverless?
- Onde armazenarei meus “objetos” (documentos, arquivos, imagens, etc.)? Através da Amazon S3, Google Cloud Storage, Azure Blob ou outra solução?
- Ademais, qual o suporte a CDN (Content Delivery Network) em cada uma das soluções? Em quais produtos está integrado?
- Devo escalar verticalmente ou horizontalmente? Qual das opções é mais viável para minha situação atual?
- Quais os parâmetros de escalabilidade utilizarei para incrementar ou decrementar instâncias?
- A solução contém um mecanismo de DNS (Route 53, etc.)?
- Por fim, qual o custo mensal de todos os recursos que necessito?
5.7— Verificando custos
- AWS
Calculadora de preço para AWS Lambda — Serverless computing
- Google Cloud Storage
Calculadora de preço para Google Cloud Function — Servlerless computing
- Azure
Calculadora de preço para Azure Function — Serverless computing
6. Agradecimentos
Finalmente espero que este artigo tenha contribuído de alguma forma sobre a arquitetura das APIs RESTful. O passo após a publicação da API é o monitoramento. Tentei resumir alguns pontos importantes e traze-los para discussão neste artigo. Espero que tenham um bom proveito. Desejo que o conteúdo ajude enquanto arquitetando uma api restful.
Sempre que desejar, acesse mais conteúdo igual a esse clicando aqui.
Referências:
Capitulo 5 da Tese de Doutorado de Roy Fielding. Disponível em https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm.
Artigos de Marcos Mendes. Disponível em https://marco-mendes.com/arquitetura/.
Melhores práticas para o design de APIs RESTFUL pragmáticas. Disponível em https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api.
Imagens disponibilizadas pelo Pluralsight. Disponível em https://www.pluralsight.com/blog/tutorials/representational-state-transfer-tips.
Http basics. Disponível em https://www.ntu.edu.sg/home/ehchua/programming/webprogramming/HTTP_Basics.html.
API da Marvel. Disponível em https://developer.marvel.com/docs.
Developer Mozilla. Disponível em https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status.
Tabela de métodos. Disponível em https://medium.com/@kumaraksi/using-http-methods-for-restful-services-e6671cf70d4d.
Notas sobre idempotencia. Disponível em https://stackoverflow.com/questions/4088350/is-rest-delete-really-idempotent
RFC 2616. Disponível em https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.
RFC 7231. Disponível em https://tools.ietf.org/html/rfc7231#section-4.2.2.
Martin Fowler — Modelo de maturidade de Richardson. Disponível em https://martinfowler.com/articles/richardsonMaturityModel.html.
Melhores práticas para Logs. Disponível em https://www.loomsystems.com/blog/single-post/2017/01/26/9-logging-best-practices-based-on-hands-on-experience.
Rest Api Design. Disponível em https://www.codepedia.org/ama/tutorial-rest-api-design-and-implementation-in-java-with-jersey-and-spring/.
RestFul web service with Jersey. Disponível em https://o7planning.org/en/11207/simple-crud-example-with-java-restful-web-service.
RestFul webservice with Python. Disponível em https://kite.com/blog/python/flask-restful-api-tutorial/.
RestFul webservice with Elixir. Disponível em https://dev.to/plutov/building-rest-server-with-elixir-4pd.
RestFul webservice with Php Laravel. Disponível em https://www.toptal.com/laravel/restful-laravel-api-tutorial.
RestFul webservice with Rust. Disponível em https://www.toptal.com/laravel/restful-laravel-api-tutorial.
RestFul webservicw with Go. Disponível em https://medium.com/@rafaelacioly/construindo-uma-api-restful-com-go-d6007e4faff6.
RestFul webservicw with Dart. Disponível em https://medium.com/@rafaelacioly/construindo-uma-api-restful-com-go-d6007e4faff6.
Top cloud providers 2019. Disponível em https://www.zdnet.com/article/top-cloud-providers-2019-aws-microsoft-azure-google-cloud-ibm-makes-hybrid-move-salesforce-dominates-saas/.