Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development
Code

Guia de introdução aos conceitos HTTP e REST

by
Difficulty:IntermediateLength:LongLanguages:

Portuguese (Português) translation by thierry rene matos (you can also view the original English article)

Hypertext Transfer Protocol ou HTTP é a alma da web. É utilizado todas as vezes que você transfere um documento, ou faz uma solicitação AJAX. Mas o conceito do HTTP não é tão difundido entre desenvolvedores.

Nessa introdução vamos entender como um conjunto de princípios de design, conhecido como REST, com suporte HTTP, permite criar aplicações com recursos bem interessantes, que podem ser utilizadas em diversas plataformas e sistemas.

Tutorial republicado 

Todas as semanas, damos uma olhada nos posts mais visitados durante a história do site. Esse tutorial foi originalmente publicado em Novembro de 2010.


Porque REST?

REST é uma maneira simples de organizar interações em sistemas independentes.

REST é uma maneira simples de organizar interações em sistemas independentes. Sua popularidade vem crescendo desde 2005, o que inspira o design de serviços, como por exemplo a API do Twitter. Isso está relacionado ao fato do REST permitir a interação com diversos clientes sem stress, tanto em dispositivos móveis quanto qualquer outro website/serviço.  Na teoria, REST não tem nada a ver com web, mas o conceito é amplamente utilizado na área, e foi inspirado pelo HTTP. Como resultado, onde existe HTTP, o REST pode ser utilizado.

A alternativa é criar convenções relativamente complexas em cima do HTTP. As vezes, isso nos leva a novas linguagens baseadas no XML. O melhor exemplo disso é o SOAP Você precisa aprender por completo um conjunto de novas convenções, mas você nunca vai utilizar o HTTP com todos os seus recursos. Como o REST foi inspirado pelo HTTP e utiliza sua base, é melhor entendermos primeiro como o HTTP de fato funciona.

Depois desta introdução, vamos analisar cada parte do HTTP: URLs, verbos HTTP e códigos de resposta. Também vamos conferir como utilizar essas informações de maneira RESTful. Durante o artigo, vamos tentar ilustrar a teoria com uma aplicação de exemplo, que simula o processo de monitorar o tráfego de informações de uma empresa através de uma interface web.


HTTP

HTTP é um protocolo que permite enviar e receber informações na web.

HTTP é um protocolo que permite enviar e receber informações na web. Um protocolo é um conjunto de regras que determinam que tipo de informações podem ser trocadas, e que mensagens são apropriadas para encaminhar a terceiros. Outro protocolo bem conhecido é o POP3, que você pode utilizar para receber emails no seu desktop.

No HTTP, existem dois papeis responsáveis pelo funcionamento correto do protocolo: o servidor e o cliente. Por padrão, o cliente sempre inicia a conversa; e então o servidor responde. Criando uma comunicação. O HTTP é baseado em texto; ou seja, mensagens são essencialmente uma fração de bits de dados, mas o corpo da mensagem pode conter outros arquivos de mídia.  A utilização de texto facilita a forma como monitoramos requisições HTTP.

Mensagens HTTP são feitas a partir de um header e um body. O body as vezes pode ser vazio; ele contém informações que você deseja transmitir através da rede, de acordo com as instruções presentes no header. O header guarda as informações metadata, como por exemplo o encode; mas, no caso de requisições, ele também pode conter informações como HTTP methods, ou métodos HTTP.  No estilo REST, você vai notar que as informações do header são mais importantes e significantes que as informações do body.


Monitorando o HTTP no trabalho

Se você utiliza o Chrome Developer Tools, ou o Firebug no Firefox (extensão instalável), clique no painel Net, e marque ele como enabled/ativado. Agora você consegue ver os datalhes das requisições HTTP enquanto navega. Por exemplo:

Screenshot of Firebug Net panel

Outra maneira de se familiarizar com o HTTP é utilizar um cliente dedicado, como o cURL.

cURL é uma ferramenta de linha de comando disponível nos principais sistemas operacionais.

Assim que você tiver o cURL instalado, digite:

A ação do comando vai apresentar toda conversa entre o protocolo HTTP. Requisições são precedidas de >, enquanto repostas são precedidas de <.


URLS

URLs é como indentificamos os itens que queremos operar. Cada URL identifica um recurso. Essas são as mesmas URLs que são atribuidas a páginas da web. De fato, uma página da web é um tipo de recurso. Vamos analisar um exemplo mais exótico, considerando nossa aplicação de exemplo, que gerencia a lista de clientes de uma empresa:

vamos indentificar todos os clientes, enquanto

vamos identificar o cliente, chamado "Jim", assumindo que ele é o unico com esse nome.

Nos exemplos, geralmente não incluímos o nome do host (hostname) na URL, pois é irrelevante do ponto de vista de organização da interface. Mas não ignore o nome do host, ele é importante para determinar que aquele recurso é unico na internet. É comum dizer que você envia uma solicitação/request de um recurso para um host. O host é incluso no cabeçalho/header, separado dos recursos, que ficam ao lado esquerdo.

Os recursos ficam mais fáceis de entender quando nomeados como substantivos. Por exemplo, o exemplo a seguir não é RESTful:

Isso é porque ele utiliza uma URL para descrever uma ação. Esse é um ponto crucial para distinguir sistemas RESTful de sistemas não RESTful.

Enfim, as URLs devem ser diretas e precisas, de acordo com a necessidade; qualquer coisa que identifica um recurso único deve estar na URL. Você não precisa incluir o nome que identifica a informação do recurso na requisição/request. Dessa maneira, uma URL pode atuar como um mapa de todas as informações que a aplicação suporta.

Mas como especificamos uma ação? Por exemplo, como dizer que você quer criar um novo cliente ao invés de requisitar um cliente? Para isso existem os verbos HTTP.


Verbos HTTP

Cada requisição está atrelada a um verbo HTTP, ou método, no cabeçalho de requisição. São as letras maiúsculas no início do cabeçalho. Por exemplo,

Significa que o método GET está sendo utilizado, enquanto

significa que o método DELETE está sendo utilizado.

Os verbos HTTP dizem ao servidor o que ele deve fazer com a informação identificada na URL.

Os verbos HTTP dizem ao servidor o que ele deve fazer com a informação identificada na URL. A requisição pode por opção conter informações adicionais no corpo/body, que podem ser necessárias para executar a operação - por exemplo, informações que você quer guardar com o recurso. Voce pode acessar essa informação no cURL com a opção -d.

Se você já criou formulários em HTML, você deve estar familiarizado com dois dos mais importantes verbos HTTP: GET e POST. Mas, existem muitos outros verbos HTTP disponíveis web a fora.  Os mais importantes para criar uma API RESTful são GET, POST, PUT, e DELETE. Outros métodos estão disponíveis, como o HEAD e OPTIONS, mas a utilização destes é mais rara (se você quer saber mais sobre métodos HTTP, acesse o link do IETF).

GET

GET é metodo mais simples de requisição HTTP; o mesmo que navegadores utilizam toda vez que você clica em um link ou acessa através da barra de endereços. Com as instruções, o servidor transmite a informação indentificada na URL para o cliente. As informações nunca devem ser alteradas no servidor através de uma requisição GET. Neste caso, uma requisição GET seria apenas leitura, mas claro, a partir do momento que o cliente recebe a informação, ele pode fazer o que desejar - por exemplo, formatar a informação para apresentação no browser.

PUT

Uma requisição PUT é utilizada quando desejamos criar ou atualizar uma informação identificada por uma URL. Por exemplo,

pode criar um cliente, chamado Robin no servidor. Você deve ter notado que o REST é complemente livre do backend; não há nenhuma instrução na requisição para informar ao servidor como essa informação deve ser criada. Isso permite que troquemos com facilidade a tecnologia do servidor caso haja a necessidade. Requisições PUT contém a informação utilizada para atualizar ou criar os recursos do corpo/body. no cURL, você pode adicionar informações a requisições com o parametro -d.

DELETE

O DELETE deve atuar ao contrária do PUT; deve ser utilizado quando você deseja deletar o recurso identificar pela URL, na requisição.

Isso vai vai deletar todas as informações relacionadas ao recurso, identificado no endereço /clients/anne.

POST

O POST é utilizado quando houver repetição no processo executado no servidor, ou seja, quando uma requisição POST é executada mais de uma vez. Complementando, requisições POST devem executar o processo no corpo como um subordinado da URL que você está postando.

Em outras palavras:

não deve causar modificações ao recurso presente no /clients/, por si só, e sim a um recurso identificado na URL após o /clients/. Por exemplo, pode ser a inclusão de um novo cliente na lista, com um id gerado pelo servidor.

Requisições PUT são facilmente utilizadas ao invés das requisições POST. Alguns sistemas utilizam apenas um, outros utilizam o POST para operações de criação, e o PUT para operações de atualização (com requisições PUT você sempre fornece a URL completa), outros até utilizam o POST para atualizações e o PUT para criações.

As vezes, requisições POST são utilizadas para operações de gatilhos/triggers no servidor, e que não se enquadram dentro do paradigma Create/Update/Delete; mas isso, de qualquer forma, está fora do escopo do REST. No nosso exemplo, vamos sempre utilizar o PUT.


Classificando métodos HTTP

Métodos seguros e não seguros:
Métodos seguros são aqueles que nunca modificam os recursos. O unico método seguro, dos listados acima, é o GET. Os outros não tem segurança, porque sua execução podem resultar na modificação dos recursos.

Métodos idempotentes:
Esses métodos atingem o mesmo resultado, não importa quantas vezes se repitam; são os métodos GET, PUT, e DELETE. O unico método idempotente é o POST. Os métodos PUT e DELETE serem considerados idempotentes pode causar surpresa, mas tem uma explicação simples para isso: repetir o método PUT com exatamente o mesmo corpo/body deve modificar um recurso da mesma maneira que a primeira requisição PUT: nenhuma mudança da fato vai ocorrer (devido ao mesmo corpo/body da requisição). Do mesmo modo, não faz sentido deletar um recurso duas vezes. Em suma, não importa quantas vezes uma requisição PUT ou DELETE se repita, o resultado deve ser sempre o mesmo já que a ação é executada apenas uma vez.

Lembre-se: é você, o programador, que em ultima instância define o que acontece com determinados métodos HTTP. Não há nenhuma implementação ao HTTP que pode automaticamente causar a criação, exibição, remoção ou atualização de recursos. Você deve ter muito cuidado e atenção para aplicar o protocolo HTTP corretamente e garantir as semânticas utilizadas.


Representações

O cliente HTTP e o servidor HTTP trocam informações sobre recursos identificados pelas URLs.

Podemos agregar o que aprendemos até agora da seguinte maneira: o cliente HTTP e o servidor HTTP trocam informações sobre recursos que são identificados através das URLs.

Podemos dizer que a requisição e a resposta contém uma representação daquele recurso. Com representação, queremos dizer informações, de um certo formato, sobre o estado do recurso ou como aquele estado deve estar no futuro. Tanto o cabeçalho/header quanto o corpo/body são partes da representação.

O cabeçalho HTTP, que contém a metadata, são definidos pela especificações do HTTP; podem conter apenas texto, que deve ser formatado de uma certa maneira.

O corpo/body contém informações em qualquer formato, e é aqui que o HTTP mostra todo seu poder. Você sabe que pode enviar texto, imagem, HTML e XML em qualquer linguagem humana. Através de requisições metadata ou de URLs, você pode escolher diferentes representações para o mesmo recurso. Por exemplo, você pode enviar uma pagina web para o navegador e informações JSON para aplicações.

A resposta HTTP deve especificar o tipo de conteúdo do corpo/body. Isso é feito no cabeçalho/header, no campo content-type; por exemplo:

A fim de manter a simplicidade, nossa aplicação de exemplos apenas envia de volta informações JSON, mas a aplicação deve ter um arquitetura que permita a interpretação da informação em outros formatos, para se adaptar a diferentes clientes e preferências de usuários.


Biblioteca de clientes HTTP

O cURL é, mais do que nunca, o cliente HTTP utilizado por desenvolvedores PHP.

Para testar os diferentes métodos de requisição, você vai precisar de um cliente, que permite a você especificar que método utilizar. Infelizmente, formulários HTML não se enquadram nesse caso, já que permitem apenas requisições GET e POST. Na vida real, APIs são acessadas por aplicações em clientes separados, ou através do JavaScript em navegadores.

Essa é a razão pela qual, assim como no servidor, é essencial utilizar uma linguagem de programação que ajude a utilizar toda a capacidade dos recursos HTTP.

Um cliente HTTP bem popular, novamente, é o cURL. Você já deve estar familiarizado com os comandos do cURL devido aos exemplos do tutorial. O cURL inclui tanto um programa em linha de comando, quanto uma biblioteca que pode ser utilizada por várias linguagens de programação. Em particular, o cURL é, mais do que nunca, o cliente HTTP escolhido por desenvolvedores PHP. Outras linguagens, como o Python, oferece mais bibliotecas HTTP nativas no cliente.


Configurando a Aplicação do Exemplo

Pretendo expor as funcionalidade mais simples sempre que possível.

Nossa aplicação de exemplo em PHP é bem simples. Quero expor as funcionalidades simples da linguagem sem utilizar nenhuma magica gerada por frameworks. Também não quero utilizar uma API de verdade, como a do Twitter, porque eles podem mudar o funcionamento da API a qualquer momento, você precisa configurar autenticação, o que pode levar tempo, e claro que você não estudou a implementação.

Para rodar a aplicação de exemplo, você vai precisar instalar o PHP5 em um servidor web. A versão tem de ser no mínimo a 5.2 para ter acesso as funções json_encode() e json_decode().

Para o servidor, a melhor escolha continua sendo o Apache com mod_php, mas você é livre para usar qualquer outra alternativa compatível. Tem um exemplo de configuração do Apache, que contém regras para ajudar a configurar sua aplicação. Todas as requisições para qualquer URL, começando com /clients/, devem ser encaminhadas para o arquivo server.php.

No Apache, você precisa habilitar o mod_rewrite e inserir a configuração do mod_rewrite em algum lugar da configuração do Apache, no arquivo .htacess. Dessa maneira, o arquivo server.php vai responder a todas as requisições feitas ao servidor. O mesmo deve ser feito com servidores Nginx, ou qualquer outra alternativa


Como a aplicação do exemplo funciona

Existem duas chaves para processar requisições REST. A primeira chave serve para iniciar diferentes processos, dependendo do método HTTP - mesmo quando as URLs são as mesmas. No PHP, tem uma variável na array global $_SERVER, que determina qual o método foi utilizado para fazer a requisição:

Essa variável trás o nome do método como uma string, por exemplo, 'GET', 'PUT', e assim por diante.

A outra chave é para saber qual URL foi requisitada. Para isso, utilizamos outra variável padrão do PHP:

Essa variável contém a URL começando a partir da primeira barra. Por exemplo, se o nome do host é 'exemplo.com', 'http://examplo.com/' poderia retornar '/', enquanto 'http://examplo.com/teste/' poderia retornar '/teste/'.

Vamos primeiro determinar qual URL foi requisitada. Vamos apenas considerar URLs começando com 'clients'. Qualquer outra URL é inválida.

Temos duas possíveis opções de saída de dados:

  • O recurso são os clientes, neste caso, retornamos uma lista completa.
  • Existe um identificar adicional.

Se existe um identificador adicional, assumimos que este é o nome do cliente, e, encaminhamos este para uma função diferente, dependendo do método. Utilizamos um switch case, que deve ser evitado em aplicações reais:


Códigos de resposta

Os códigos de resposta HTTP padronizam a maneira como o cliente é informado sobre o resultado de suas requisições. 

Você deve ter notado que a aplicação de exemplo utiliza o PHP header(), com algumas strings bem estranhas como argumentos. A função header() apresenta os headers HTTP e garante que eles estão formatados corretamente. O cabeçalho/header deveria ser o primeiro item da resposta, assim você não precisaria fazer mais nada após a leitura do header. As vezes, nosso server HTTP pode estar configurado para adicionar outros headers, em conjunto com aqueles já configurados no seu código.

O cabeçalho/header contém todo tipo de meta informação; por exemplo, encode de texto utilizado no corpo/body da mensagem ou o MIME type do conteúdo do body. Neste caso, estamos explicitamente especificando os códigos de resposta HTTP. Os códigos de resposta HTTP são uma maneira de padronizar a forma como informamos ao cliente sobre suas requisições. Por padrão, o PHP retorna o código de resposta 200, que significa que a resposta foi OK.

O servidor deve retornar o código de resposta HTTP mais apropriado; dessa maneira, o cliente tem um caminho para resolver o seu problema, desde que haja algum. Muitas pessoas estão acostumadas com a resposta de erro 404 página não encontrada, mas, além desta existem vários outros erros para diversas situações.

Tenha em mente que as respostas HTTP não são extremamente precisas; essa é uma consequência do próprio HTTP que é bem genérico. Você deve tentar utilizar o código de resposta que mais se enquadra na situação do momento. Em suma, não se preocupe tanto se você não conseguir enquadrar um erro.

Aqui estão alguns códigos de resposta HTTP, que geralmente são utilizado com REST:

200 OK

Essa resposta indica que a requisição foi bem sucedida. 

201 criação OK

Este indica que a requisição e a criação de um recurso foram bem sucedidas. É utilizado para confirmar se as requisições PUT ou POST foram bem sucedidas.

400 solicitação inválida

A requisição não foi feita corretamente. Isso acontece especialmente com requisições POST e PUT, quando as informações não são validadas, ou estão no formato errado.

404 página não encontrada

Essa resposta indica que o recurso requisitado não pode ser encontrado. Essa reposta é geralmente utilizada para as requisições que apontam para uma URL inexistente.

401 não autorizado

Esse erro indica que você precisa primeiro estar autenticado para acessar o recurso.

405 método não permitido

O método HTTP utilizado não é suportado por este recurso.

409 conflito

Este indica um conflito na requisição. Por exemplo, você está utilizando uma requisição PUT para criar o mesmo recurso duas vezes.

500 erro interno do servidor

Quando todos os outros falham; geralmente, o código de reposta 500 é apresentado quando o processamento falha devido a circunstâncias do servidor, o que causa erro no servidor.


Se exercitando com a aplicação de exemplo

Vamos começar separando as informações da aplicação. Queremos os detelhes do cliente 'jim', então vamos executar uma requisição GET para a URL deste recurso: 

Isso deve apresentar o cabeçalho completo das mensagens. A ultima linha na resposta vai ser a mensagem do corpo, ou message body; neste caso, a resposta com informações do jim estão em formato JSON (lembre que omitir o nome de um método pode resultar em uma requisição GET; também altere o localhost:80 pelo link do servidor e porta que você está utilizando).

Seguindo, podemos obter as informações de todos os clientes de uma vez:

Para criar um novo cliente, chamado Paul...

e você vai receber uma lista com todos os clientes com nome Paul como confirmação.

E finalmente, para deletar um cliente:

Note que o JSON retornado na resposta não contém nenhuma informação sobre Anne.

Se você tentar requisitar um cliente que não existe, por exemplo:

Você vai receber o erro 404, enquanto, se você tentar criar um cliente que já existe:

curl -v -X PUT http://localhost:80/clients/anne

Você vai receber como retorno o erro 409.


Conclusão

Em geral, quanto menos requisições HTTP você fizer, melhor.

É importante lembrar que o HTTP foi concebido para se comunicar entre sistemas, que basicamente compartilham uma compreensão do protocolo. Em geral, quando menos requisições HTTP você fizer, melhor: isso permite que uma gama de programas e dispositivos acessem sua API.

Utilizamos PHP neste tutorial, porque é a linguagem mais familiar para leitores do Nettuts+. Com isso, o PHP, mesmo sendo criado para web, provavelmente não é a melhor linguagem quando a intenção é trabalhar com REST, já que requisições PUT são tratadas de outra maneira em relação ao GET e POST

Deixando o PHP um pouco de lado, você deve se preocupar com o seguinte:

Entre as aplicações que gostaria de indicar para iniciantes em REST, está o clássico exemplo Atom Publishing Protocol, mas na prática ele não é muito utilizado. Para uma aplicação moderna, criada com a intenção de utilizar o HTTP por completo, dê uma olhada no Apache CouchDB.

Divirtam-se!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.