Descobrindo APIs REST

Post on 28-Jun-2015

393 views 3 download

description

O crescimento do mercado mobile e a necessidade de prover acesso a serviços existentes para desenvolvedores terceiros popularizaram o uso e disponibilização de APIs REST públicas. Com isso, pontos como escalabilidade, versionamento, desacoplamento e encapsulamento tornaram-se centrais no projeto de APIs. Nesta palestra será apresentado o conceito de APIs Hypermedia e como seu uso ajuda no projeto e implementação de APIs mais flexíveis.

Transcript of Descobrindo APIs REST

Descobrindo

APIs REST

Guilherme Cavalcantigithub.com/guiocavalcanti

Por quê?

Definição Hermética

Como? Por quê?

intridea/grape

apotonick/roar

lostisland/sawyer

jsonapi.org

kevinswiber/siren

caelum/restfulie

What the f* isRepresentational State Transfer

–Roy Fielding

“I am getting frustrated by the number of people calling any HTTP-based interface a

REST API.”

Como?

• Problema conhecido por todos

• Passo a passo para projetar e implementar uma API REST

• Erros comuns, trade-offs e falácias

O que é rest e hypermedia?

• Estilo arquitetural

• Restrições

O que é REST/Hypermedia?

• Construção de sistemas distribuídos

• Em 99% dos casos sistemas que funcionam na Web

• Aplicativos mobile conversando com APIs

• Aplicativos Web convesando com Aplicativos Web

• Walledgarden

O processo

1. Entender o workflow que a API irá implementar

2. Construir máquina de estados

3. Construir media types

4. Implementar :)

Entender o workflow

Entender workflow

• Pensar em termos de processos de negócio

• Quantos e quais passos serão necessários?

PedidoPagamento

O Problema

• Ciclo de pedido

• Ciclo de pagamento

• Independentes

• Comunicação assíncrona através de message queue

• Maximiza throughput

PedidoPagamentoMessage Queue

Simplificado

• Na verdade são 3 ciclos independentes

• Mais lucros

• Dica: Starbucks Does Not Use Two-Phase Commit

Criar máquina de estados

Criar máquina de estados: cliente

Sanduíche preparado

Pagamento realizado

Sanduíche entregue

Pedir Pagar Pegar

Atualizar

Caixa

Sanduíche Escolhido

Pagamento Lançado

Escolher pedido

Lançar pagamento

Construir media type

( o que é media type? )

–Roy T. Fielding

“To some extent, people get REST wrong because I failed to include enough detail on media type design within my dissertation.

That’s because I ran out of time […]”

Media types

• É o que o cliente precisa saber para entender:

• Comportamento (ou seja, quais transições saem de ume estado)

• Semântica de alguns atributos da representação

Exemplo: text/html

• Ao clicar no <a>: Requisição GET  para href

• Ao submeter um <form>: Requisição method para action

Exemplo: text/html

• O browser só precisa entender o media type.

• Tanto faz se você está vendo o extrato da sua conta do banco ou um verbete na Wikipedia

• media type = comportamento + semântica

Exemplo: APIs

• Erros de validação

• Internacionalização de mensagens

• URLs

Media types

• É por isso que sempre dizem que APIs REST não precisam de Documentação

• Você só precisa descrever os media types utilizados

• A semântica dos métodos HTTP já é bem definida

• Utilizado nos cabeçalhos Accept e Content-­‐type

Voltando: Construir media type

Voltando: Construir media type

application/vnd.subway.sanduiche-­‐v1+json

Feito por terceiros

Nome

Variante

Sanduíche

Sanduíche: Semântica• id  

• created_at  

• pao  

• queijo  

• status  

• updated_at

Pagamento: Semântica

• id  

• created_at  

• numero_cartao  

• expira_em  

• valor

Semântica

• Atributos que tem o mesmo significado para todos os recursos da API

• Comportamentos inesperados (erros de validação)

Comportamento: Relacionamentos

{      "links":  [          {  "rel":  "self",  "href":  "/pedidos/1"  },          {  "rel":  "pagamento",  "href":  "/pagamentos/pedidos/1"  }      ]  }

Comportamento: Relacionamentos

• Representam as transições da nossa máquina de estados

• Aumentam o desacoplamento

• O cliente não precisa saber URLs a priori

Mas… Quais métodos utilizar?

–Roy T. Fielding

“[…] methods are not given meaning by the media type. Instead, the media type tells the client either

what method to use (e.g., anchor implies GET) or how to determine the method to use (e.g., form element says to look in method attribute). The client should already know what the methods mean (they are

universal) and how to dereference a URI.”

HTTP Methods• GET

• POST

• PUT

• PATCH

• DELETE

• OPTIONS

“ Rails is not restful “ Kind of comment…

Implementar

Sanduíche preparado

Pagamento realizado

Sanduíche entregue

Pedir Pagar Pegar

Atualizar

Fazer pedido: Requisição

POST  /pedidos  HTTP/1.1  Accept:  application/vnd.subway.sanduiche-­‐v1+json {          "pao":  "3queijos",          "queijo":  "suíço",          "recheio":  "club"  }

Fazer pedido: RespostaHTTP/1.1  201  Created  Content-­‐type:  application/vnd.subway.sanduiche-­‐v1+json {      "id":  "1",      "created_at":  "2013-­‐10-­‐23T05:02Z",      "updated_at":  null,      "pao":  "3  queijos",      "queijo":  "suíço",      "recheio":  "club",      "status":  “em  preparo",      "links":  [          {  "rel":  "self",  "href":  "/pedidos/1"  },          {  "rel":  "pagamento",  "href":  "/pagamentos/pedidos/1"  }      ]  }

Atualizar pedido: Requisição

PATCH  /pedidos/1  HTTP/1.1  Accept:  application/vnd.subway.sanduiche-­‐v1+json {          "queijo":  "cheddar"  }

Atualizar pedido: RespostaHTTP/1.1  200  Ok  Content-­‐type:  application/vnd.subway.sanduiche-­‐v1+json {      "id":  "1",      "created_at":  "2013-­‐10-­‐23T05:02Z",      "updated_at":  null,      "pao":  "3  queijos",      "queijo":  "cheddar",      "recheio":  "club",      "links":  [          {  "rel":  "self",  "href":  "/pedidos/1"  },          {  "rel":  "pagamento",  "href":  "/pagamentos/pedidos/1"  }      ]  }

Atualizar pedido: ErroHTTP/1.1  409  Conflict  Content-­‐type:  application/vnd.subway.sanduiche-­‐v1+json {      "id":  "1",      "created_at":  "2013-­‐10-­‐23T05:02Z",      "updated_at":  null,      "pao":  "3  queijos",      "queijo":  "suiço",      "recheio":  "club",      "links":  [          {  "rel":  "self",  "href":  "/pedidos/1"  },          {  "rel":  "pagamento",  "href":  "/pagamentos/pedidos/1"  }      ]  }

Como saber se é possível mudar o pedido?

OPTIONS  /pedidos/1  HTTP/1.1

HTTP/1.1  200  Ok  Allow:  GET,  PATCH

Pagar pedido: REQUISIÇÃO

• Lembra do media type?

• Utilizar relacionamentos

Pagar pedido: REQUISIÇÃO

GET  /pagamentos/pedidos/1  HTTP/1.1  Accept:  application/vnd.subway.sanduiches-­‐v1+json {          "numero_cartao":  "123312",          "expira_em":  "12/12",          "valor":  "12.45"  }

Ponto de vista do caixa: fila de sanduíches

GET  /pedidos  HTTP/1.1  Accept:  application/vnd.subway.sanduiches-­‐v1+json{      "total":  12,      "page":  1,      "per_page":  10,      "items":  [          {  "id":  “1”,  “status”:  "pago"  …  },          {  "id":  “2”,  “status”,  “em  preparo"  …  }      ]  }

Listar pedido: media type

• É necessário criar seu próprio media type?

• Não! Já existem vários:

• collection+json

• atom+xml

Gems

roar

beer  =  Beer.new(:title  =>  "Lonestar  Beer")  beer.post(order.links[:items])

jsonapi.org

• Media type de propósito geral

• Links, Coleções, etc

Obrigado :)

Referências• http://www.infoq.com/articles/webber-rest-workflow

• http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html

• http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

• http://github.com/apotonick/roar

• http://github.com/intridea/grape

• http://jsonapi.org