Então, eu estava olhando alguns artigos sobre a criação de APIs REST. E alguns deles sugerem o uso de todos os tipos de solicitações HTTP: como PUT
DELETE
POST
GET
. Nós criaríamos, por exemplo, index.php e escreveríamos a API desta maneira:
$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));
switch ($method) {
case 'PUT':
....some put action....
break;
case 'POST':
....some post action....
break;
case 'GET':
....some get action....
break;
case 'DELETE':
....some delete action....
break;
}
OK, garantido - ainda não sei muito sobre serviços da web. Mas, não seria mais fácil aceitar o objeto JSON por meio de regular POST
ou GET
(que conteria o nome do método e todos os parâmetros) e, em seguida, responderia em JSON também. Podemos facilmente serialize / deserialize via PHP de json_encode()
e json_decode()
e fazer o que quisermos com esses dados sem ter que lidar com diferentes métodos de solicitação HTTP.
Estou esquecendo de algo?
ATUALIZAÇÃO 1:
Ok - depois de pesquisar várias APIs e aprender muito sobre XML-RPC , JSON-RPC , SOAP , REST , concluí que esse tipo de API é válido. Na verdade, o intercâmbio de pilhas está usando essa abordagem em seus sites e acho que essas pessoas sabem o que estão fazendo na API do Stack Exchange .
Respostas:
A idéia de RE apresentação S tate T ransferência não é sobre o acesso a dados da forma mais simples possível.
Você sugeriu o uso de solicitações de postagem para acessar o JSON, que é uma maneira perfeitamente válida de acessar / manipular dados.
O REST é uma metodologia para acesso significativo aos dados. Quando você vê uma solicitação no REST, deve ser aparente imediatamente o que está acontecendo com os dados.
Por exemplo:
provavelmente retornará uma lista de carros chevy.
Uma boa API REST pode até incorporar algumas opções de saída na string de consulta como?output=json
ou?output=html
que permitiriam ao acessador decidir em qual formato a informação deveria ser codificada.Após um pouco de pensamento sobre como digitação de dados razoavelmente incorporar em uma API REST, cheguei à conclusão que a melhor maneira de especificar o tipo de dados explicitamente seria através da extensão de arquivo já existente, como
.js
,.json
,.html
, ou.xml
. Uma extensão de arquivo ausente será padronizada para qualquer formato padrão (como JSON); uma extensão de arquivo não suportada pode retornar um501 Not Implemented
código de status .Outro exemplo:
provavelmente criará um novo chevy malibu no banco de dados com as cores associadas. Eu digo que provavelmente como a API REST não precisa estar diretamente relacionada à estrutura do banco de dados. É apenas uma interface de máscara para proteger os dados verdadeiros (pense nisso como acessadores e mutadores para uma estrutura de banco de dados).
Agora precisamos avançar para a questão da idempotência . Normalmente, o REST implementa o CRUD sobre HTTP. HTTP usa
GET
,PUT
,POST
eDELETE
para as solicitações.Uma implementação muito simplista do REST poderia usar o seguinte mapeamento CRUD:
Há um problema com esta implementação: Post é definido como um método não idempotente. Isso significa que chamadas subseqüentes do mesmo método Post resultarão em diferentes estados do servidor. Get, Put e Delete são idempotentes; o que significa que chamá-los várias vezes deve resultar em um estado de servidor idêntico.
Isso significa que uma solicitação como:
poderia realmente ser implementado como:
Enquanto que
resultará no mesmo estado do servidor se você chamá-lo uma vez ou se você chamar 1000 vezes.
Uma maneira melhor de lidar com a remoção do
oldest
item seria solicitar:e use os
ID
dados resultantes para fazer umadelete
solicitação:Um problema com esse método seria se outro
/cars
item fosse adicionado entre quando/oldest
foi solicitado e quandodelete
foi emitido.fonte
POST: /cars/oldest
ser um substituto para um DELETE não faz muito sentido. Algo como -POST: /cars/oldest/delete
pode, acho que gosto mais da solução de Neil. A única vantagem que uma exclusão direta oferece sobre sua solução get-id-delete-id é a atomicidade. Eu gostaria de uma justificativa comercial clara com um cenário não artificial antes de implementar uma coisa dessas. Você não precisa suportar todos os verbos em todos os objetos / URLs.Esta é uma questão de segurança e manutenção.
métodos seguros
Sempre que possível, você deve usar métodos 'seguros' (unidirecionais), como GET e HEAD, para limitar a vulnerabilidade em potencial.
métodos idempotentes
Sempre que possível, você deve usar métodos 'idempotentes', como GET, HEAD, PUT e DELETE, que não podem ter efeitos colaterais e, portanto, são menos propensos a erros / mais fáceis de controlar.
Fonte
fonte
Em suma, o REST enfatiza substantivos sobre verbos. À medida que sua API se torna mais complexa, você adiciona mais coisas, em vez de mais comandos.
fonte
Você perguntou :
Da Wikipedia em REST :
Pelo que (pouco) eu vi, acredito que isso geralmente é realizado maximizando o uso de verbos HTTP existentes e criando um esquema de URL para o seu serviço que seja o mais poderoso e evidente possível.
Os protocolos de dados personalizados (mesmo que sejam criados sobre os padrões, como SOAP ou JSON) são desencorajados e devem ser minimizados para melhor se adaptar à ideologia REST.
Os objetos reais com os quais você está trabalhando podem estar em qualquer formato. A idéia é reutilizar o máximo de HTTP possível para expor suas operações que o usuário deseja executar nesses recursos (consultas, gerenciamento / mutação de estado, exclusão).
Você perguntou :
Há muito mais a saber sobre o REST e os próprios verbos de sintaxe / HTTP do URI. Por exemplo, alguns dos verbos são idempotentes, outros não. Eu não vi nada sobre isso na sua pergunta, então não me incomodei em tentar mergulhar nela. As outras respostas e a Wikipedia têm muitas informações boas.
Além disso, há muito o que aprender sobre as várias tecnologias de rede criadas sobre HTTP, das quais você pode tirar proveito se estiver usando uma API realmente tranquila. Eu começaria com autenticação.
fonte
No que diz respeito ao uso da extensão para definir o tipo de dados. Notei que a API do MailChimp está fazendo isso, mas não acho que seja uma boa ideia.
Parece uma boa ideia, mas acho que a abordagem "mais antiga" é melhor - usando cabeçalhos HTTP
Além disso, os cabeçalhos HTTP são muito melhores para comunicação entre tipos de dados (se alguém precisar)
fonte
Sim. ;-)
Esse fenômeno existe devido à restrição de interface uniforme . O REST gosta de usar padrões já existentes em vez de reinventar a roda. O padrão HTTP já provou ser altamente escalável (a web está funcionando por um tempo). Por que devemos consertar algo que não está quebrado ?!
nota: A restrição de interface uniforme é importante se você deseja dissociar os clientes do serviço. É semelhante à definição de interfaces para classes, a fim de separá-las uma da outra. Claro. aqui a interface uniforme consiste em padrões como HTTP , tipos MIME , URI , RDF , vocabs de dados vinculados , vocabulário hidra , etc.
fonte
A boa semântica é importante na programação.
A utilização de mais métodos além do GET / POST será útil, pois aumentará a legibilidade do seu código e facilitará a manutenção.
Por quê?
Porque você sabe que o GET recuperará dados da sua API. Você sabe que o POST adicionará novos dados ao seu sistema. Você sabe que o PUT fará atualizações. DELETE excluirá linhas etc, etc,
Normalmente, estruturo meus Serviços Web RESTFUL para que eu tenha um retorno de chamada de função nomeado da mesma maneira que o método.
Eu uso PHP, então eu uso function_exists (eu acho que é chamado). Se a função não existir, eu jogo um 405 (MÉTODO NÃO PERMITIDO).
fonte
Bill Venners: Em sua postagem no blog intitulada "Por que o REST falhou", você disse que precisamos dos quatro verbos HTTP - GET, POST, PUT e DELETE - e lamentou que os fornecedores de navegadores apenas GET e POST. "Por que precisamos dos quatro Por que GET e POST não são suficientes?
Elliotte Rusty Harold: Existem quatro métodos básicos no HTTP: GET, POST, PUT e DELETE. GET é usado na maioria das vezes. É usado para qualquer coisa segura, que não cause efeitos colaterais. O GET pode ser marcado, armazenado em cache, vinculado a, passado por um servidor proxy. É uma operação muito poderosa, uma operação muito útil.
O POST, por outro lado, é talvez a operação mais poderosa. Pode fazer qualquer coisa. Não há limites para o que pode acontecer e, como resultado, você deve ter muito cuidado com isso. Você não adiciona aos favoritos. Você não o armazena em cache. Você não a busca previamente. Você não faz nada com um POST sem perguntar ao usuário. Você quer fazer isso? Se o usuário pressionar o botão, você poderá POSTAR algum conteúdo. Mas você não verá todos os botões de uma página e começará a pressioná-los aleatoriamente. Por outro lado, os navegadores podem olhar para todos os links da página e buscá-los previamente, ou aqueles que eles acham que provavelmente serão seguidos a seguir. De fato, alguns navegadores, extensões do Firefox e várias outras ferramentas tentaram fazer isso em um ponto ou outro.
PUT e DELETE estão no meio entre GET e POST. A diferença entre PUT ou DELETE e POST é que PUT e DELETE são * idempotentes, enquanto POST não é. PUT e DELETE podem ser repetidos, se necessário. Digamos que você esteja tentando fazer upload de uma nova página para um site. Digamos que você queira criar uma nova página em http://www.example.com/foo.html, para que você digite seu conteúdo e coloque-o nesse URL. O servidor cria essa página no URL que você fornece. Agora, vamos supor que, por algum motivo, sua conexão de rede fique inoperante. Você não tem certeza, a solicitação foi concluída ou não? Talvez a rede esteja lenta. Talvez houvesse um problema no servidor proxy. Portanto, não há problema em tentar de novo ou de novo - quantas vezes você quiser. Porque COLOCAR o mesmo documento no mesmo URL dez vezes não será diferente de colocá-lo uma vez. O mesmo vale para DELETE. Você pode excluir algo dez vezes e é o mesmo que excluí-lo uma vez.
Por outro lado, o POST, pode causar algo diferente a cada vez. Imagine que você está saindo de uma loja online pressionando o botão comprar. Se você enviar a solicitação POST novamente, poderá acabar comprando tudo no seu carrinho pela segunda vez. Se você o enviar novamente, você o comprará pela terceira vez. É por isso que os navegadores precisam ter muito cuidado ao repetir as operações do POST sem o consentimento explícito do usuário, porque o POST pode causar duas coisas se você fizer isso duas vezes, três coisas se você fizer isso três vezes. Com PUT e DELETE, há uma grande diferença entre zero pedidos e um, mas não há diferença entre um pedido e dez.
Por favor, visite o URL para mais detalhes. http://www.artima.com/lejava/articles/why_put_and_delete.html
Atualizar:
Métodos idempotentes idempotentes Um método HTTP idempotente é um método HTTP que 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 ser o mesmo. Novamente, isso se aplica apenas ao resultado, não ao próprio recurso. Isso ainda pode ser manipulado (como um registro de data e hora da atualização, desde que essas informações não sejam compartilhadas na representação de recurso (atual)).
Considere os seguintes exemplos:
O primeiro exemplo é idempotente: não importa quantas vezes executemos essa instrução, a sempre será 4. O segundo exemplo não é idempotente. A execução disso 10 vezes resultará em um resultado diferente da execução 5 vezes. Como os dois exemplos estão alterando o valor de a, ambos são métodos não seguros.
fonte
Basicamente, o REST é ( wiki ):
REST não é protocolo, é princípios. Uris e métodos diferentes - alguém chamado de melhores práticas.
fonte