Estilo RESTful
A abordagem RESTful para o desenvolvimento de web services é caracterizada pela sua informalidade e simplicidade se comparada com a abordagem baseada no protocolo SOAP.
O termo RESTful, ou simplesmente REST é o acrônimo de Representational State Transfer (Transferência de Estado Representacional) e foi criado por Roy Fielding em 2000.
RESTful é um estilo arquitetural, ou seja, é um modo de organizar a aplicação, um modo de fazer as coisas. Isso contrasta com a abordagem SOAP que é um protocolo de comunicação.
A principal motivação do estilo RESTful é a simplicidade (se comparada com SOAP) em definir e consumir os serviços da aplicação pois baseia-se exclusivamente no protocolo HTTP.
Definindo Serviços
Cada serviço disponibilizado pela aplicação é definido por: a) um end point na forma de URL e b) um método HTTP.
Os métodos HTTP definem a seguinte semântica para cada serviço:
GET | POST | PUT | DELETE |
---|---|---|---|
Obter dados, sem causar alterações no lado servidor. | Criar um novo dado no lado servidor. | Alterar um dado existente no lado servidor. | Remover um dado no lado servidor. |
Como exemplo, imagine que uma aplicação disponibiliza o seguinte serviço:
GET para http://api.empresa.com/produtos/560
O end point /produtos/560 e o método GET definem como obter os dados relacionados a um produto identificado pelo númeo 560. A resposta tipicamente é representada no formado JSON ou XML.
Uma aplicação que deseje obter informações a respeito do produto 560 deve fazer simplesmente uma requisição HTTP como mostrado acima.
Se por outro lado, o objetivo for remover o produto 560 então o serviço para isso deve ser:
DELETE para http://api.empresa.com/produtos/560
Observe que a URL é rigorosamente a mesma, a única diferença está no método (GET ou DELETE) usado.
Se o objetivo for alterar o produto 560 então o serviço para isso deve ser:
PUT para http://api.empresa.com/produtos/560
Os dados a serem alterados (preço e nome do produto) podem ser definidos na própria URL:
PUT para http://api.empresa.com/produtos/560?preco=50.30&nome=margarina
ou então fazerem parte do corpo da mensagem.
O desenvolvedor de web services que utilizam a abordagem REST tem total liberdade de definir precisamente quais os serviços estão disponíveis.
Por exemplo, se os diversos serviços fornecidos (diversos end points, portanto) admitirem apenas operação de leitura (nada pode ser alterado no lado do servidor) então basta definir que só serão analisadas requisições que contenham o método GET. Todas as demais podem ser sumariamente ignoradas (retornando, por exemplo, um JSON padrão indicando que a requisição é inválida).
Consumindo Serviços
A aplicação consumidora de web services especificados no estilo REST deve saber exatamente qual o padrão de URL para cada serviço. Invocar a execução do serviço implica unicamente em fazer uma requisição HTTP para o endereço correto.
Mas como saber quais as URLs disponíveis em um web service? Ao contrário da abordagem SOAP (onde os serviços são descritos em XML), na abordagem REST é preciso consultar a documentação (páginas HTML) explicando como invocar cada serviço. Uma boa documentação facilita a popularização dos serviços oferecidos.
GraphQL
As abordagens SOAP e REST possuem uma característica comum: os dados contidos na resposta enviada por um web service sempre são fixos, definidos no momento da sua especificação. Assim, cabe ao consumidor do serviço filtrar os dadados que lhe interessam, descartando os demais.
O Facebook criou uma espeficicação chamada GraphQL onde o consumidor dos serviços define quais dados ele está interessado. Assim, transitam pela rede apenas os dados solicitados.
GraphQL é uma variação da abordagem REST onde todos os serviços são concentrados em um único end-point (uma única URL) e cada serviço é especificado por meio da linguagem GraphQL.
Definindo Serviços GraphQL
Definir um serviço GraphQL implica em:
- Definir um esquema, usando a linguagem GraphQL, que descreve os tipos dos dados disponibilizados pelo serviço.
- Definir quais consultas podem ser realizadas para ler dados armazenados.
- Definir quais alterações, chamadas de mutações, podem ser solicitadas para alterar dados armazenados.
- Implementar algoritmos que executem as consultas e mutações.
Exemplo
Por exemplo, considere um web service que disponibiliza informações a respeito de filmes.
Definindo os tipos
A seguir estão definidos os tipos Filme
e Ator
. O ponto de exclamação significa informação obrigatória e os colchetes indicam array (um filme normalmente possui diversos atores).
type Filme {
id: ID!.
titulo: String,
ano: Integer,
atores: [Ator]
}
type Ator {
id: ID!,
nome: String,
nascimento: Integer
}
Definindo consultas possíveis
A seguir estão definidas duas consultas possíveis: a) obter todos os filmes cadastrados; b) obter todos os filmes de um determinado ano. Ambas as consultas retornam um array contendo dados sobre os filmes.
type Consultas {
todosOsFilmes: [Filme]
filmesPorAno(ano: Integer!): [Filme]
}
Consumindo Serviços GraphQL
Consumir um web service GraphSQL significa fazer uma requisição HTTP para o end-point passando também qual a consulta desejada e quais os dados que devem ser enviados na resposta.
Para o exemplo do filme, poderíamos ter as seguintes consultas:
{
todosOsFilmes
}
Essa consulta retorna um objeto JSON contendo todos os filmes cadastrados e para cada filme todas as informações cadastradas. Por exemplo, considere que há dois filmes cadastrados: "O nome da rosa" e "Um dia de fúria".
{
"data": {
"todosOsFilmes": [
{
"id": "864ab",
"titulo": "O nome da rosa",
"ano": 1986,
"atores": [
{
"id": "a200",
"nome": "Sean Connery",
"nascimento": 1930
},
{
"id": "a205",
"nome": "Michael Lonsdale",
"nascimento": 1931
}
]
},
{
"id": "821aa",
"titulo": "Um dia de fúria",
"ano": 1993,
"atores": [
{
"id": "a300",
"nome": "Michael Douglas",
"nascimento": 1944
},
{
"id": "a315",
"nome": "Robert Duvall",
"nascimento": 1931
}
]
}
]
}
}
Um dos grandes benefícios de GraphQL é que quem faz a consulta pode definir quais informações está interessado. Por exemplo, se só estivermos interessados no título dos filmes cadastrados então a consulta seria:
{
todosOsFilmes {
{
titulo
}
}
A resposta nesse caso seria:
{
"data": {
"todosOsFilmes": [
{
"titulo": "O nome da rosa",
},
{
"titulo": "Um dia de fúria",
}
]
}
}
Se desejarmos saber o título dos filmes de 1993 e os nomes dos atores a consulta seria:
{
filmesPorAno(ano = 1993) {
titulo
atores {
nome
}
}
}
A resposta a essa consulta seria:
{
"data": {
"filmesPorAno": [
{
"titulo": "Um dia de fúria",
"atores": [
{
"id": "a300",
"nome": "Michael Douglas",
"nascimento": 1944
},
{
"id": "a315",
"nome": "Robert Duvall",
"nascimento": 1931
}
]
}
]
}
}
Outra característica interessante de GraphQL é que é possível fazer várias consultas "ao mesmo tempo" reduzindo significativamente o tempo necessário para entregar a resposta HTTP ao programa cliente.
O esquema GraphQL também pode ser disponibilizado para consumo e assim saber quais as consultas estão disponíveis e quais dados podem ser solicitados.
Protocol buffers
Um web service, por definição, é reponsável por enviar dados a quem solicita. Estes dados são representados no formato XML no caso SOAP ou JSON/XML no caso REST. Ambos, XML e JSON, são representações textuais e, por isso, são fáceis de serem lidas por uma pessoa. O lado negativo é que são ineficientes se comparados com um formato binário.
O Goodle criou uma linguagem chamada protocol buffers cujo objetivo é representar esquemas de dados, no mesmo sentido dos esquemas de GraphQL, que podem ser compilados para um formato binário. Isso faz com que o processo de codificação, envio de dados e decodificação seja significativamente mais eficiente que a abordagem tradicional.
Leitura Obrigatória |
---|
Definição REST |
Overview sobre GraphQL |
Overview sobre Protocol Buffers |
Leitura Recomendada |
---|
Site oficial GraphQL |
Linguagem proto3 |