Post on 01-Jul-2015
description
Alexandria: um Sistema de Sistemas para Publicação de Conteúdo Digital utilizando
REST e Hipermídia
Luís Cipriani @lfcipriani (twitter, linkedin, github, ...)Seminário de Sistemas - IME (2013-04-08)
engineering.abril.com.br
talleye.com
hoje nós vamos falar sobre...
REST
Someone published a new REST API
Let’s check it out!! \o/
mmm...
just another HTTP-based RPC...http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
por que há tanto mal entendimento em relação ao REST?
quem entende errado, está fazendo errado?
boaarquitetura
necessidadesatendidas
custoaceitável
= + * ß
ß quão bem o seu cliente sabe pedir o que quer :-P
MTRH
MTRH mean time to recovery happiness
hoje nós vamos falar sobre...
a nossa implementação do estilo arquitetural para
sistemas baseados em rede proposto pelo Roy Fielding, mais conhecida
como...
REST
RAIO X
“organizações que projetam sistemas são restritas a produzir projetos que são cópias das estruturas de
comunicação dessas organizações”
Lei de Conway
http://www.melconway.com/Home/Conways_Law.html
gráfica
distribuidora
educação
Playboy Veja
Viaje Aqui
Recreio
Bravo!
CMS’s existem desde os anos 90.
Por que reiventamos a roda?
Porque temos alta diversidade
de
requisitosnegóciospessoas
orçamentosprioridades
culturas
{
diretoria digitalPlayboy
Bravo!
Recreio
14 sites em produção(em abr/2013)
50 desenvolvedores12 arquitetos de software
6 Gerentes de Projeto4 Gerentes de Produto
1 Advocate da Plataforma(em abr/2013)
• MongoDB• MySQL• Hbase• HDFS• PostgreSQL• memcached• redis
• ruby• java• javascript
• rails• sinatra• goliath• node.js• play• jetty• tokamak• cachebag• HTTPMonkey
linguagens storage frameworks outros
• Solr• Hadoop• RabbitMQ• Varnish• New Relic
https://github.com/abril
infraestrutura Alexandria + sites
• 91 VMs para ambientes dev, qa, stage• AMC (Abril Mídia Cloud): private cloud (Xen/Open Stack)• ou VMWare
• ~100 VMs + 16 físicas para produção• Data center próprio, AWS, Heroku
• Total aproximado: 207 máquinas (abr/2013)
12,5 milhões de pageviews(de 15/jan até 14/fev de 2013)
HTTP
domínio
• acesso e manipulação de recursos• implementa regras de negócio• servidor HTTP + base de dados• infra “isolada”• ~ 8 domínios• ex: editorial (matérias, galerias, etc), anotações (comentários), estabelecimentos, mídia, pessoas
serviço
• consumo e manipulação de recursos• servidor HTTP + (opcional base de dados)• infra “isolada”• ~ 12 serviços• ex: console, socialcore, search, Abril ID, abr.io, etc
data-entry• entrada da Redação• aplicação web• ~ 1 para cada domínio• “API explorer”
sitetools• admin do site• manipulação das áreas e templates• agiliza criação de produtos• a fronteira com o usuário• opcional
HTTP
domínio
serviço
data-entry sitetools
system of systems
REST
Por que escolhemos REST?
image from Roy Fielding dissertation (pag. 85)
REST= +LCODC$SS
Porque...
U
o_O
REST= +LCODC$SS UClient-Server
• Separação de responsabilidades• Escalabilidade (simplificação)• Evolução independente
http://byterot.blogspot.co.uk/2012/06/what-i-think-coupling-is.html
REST= +LCODC$SS UClient-Server no Alexandria
• Separação de responsabilidades • entre domínios e sites• entre domínios e data entries• entre domínios e serviços
• Escalabilidade• funcionalidade implementada nos clients• domínios só lidam com recursos (simplicidade)
• Evolução independente• em certos pontos da arquitetura não há• falta retro-compatibilidade
REST= +LCODC$SS U
• Visibilidade• Escalabilidade (recursos alocados)• Confiabilidade
• Performance de rede
Stateless
Stateless no Alexandria
• HATEOAS implementado nas APIs• cookies nas operações destrutivas
REST= +LCODC$SS U
REST= +LCODC$SS U
• Eficiência• Escalabilidade• Performance percebida pelo usuário
• Confiabilidade
Cache
Cache no Alexandria
• Built-in no protocolo HTTP• shared-caches instanciados entre alguns nós• pesquisa sobre caches locais• nem todos os nós implementam estratégia de cache• purge de recursos diretamente no cache
REST= +ULCODC$SS
REST= +LCODC$SS U
• Encapsula complexidade• Evolvabilidade• Simplicidade
• Performance percebida pelo usuário
Layered System
• shared-caches• gateways para expor API para a Web• balanceadores de carga• encapsulamento de autenticação corporativa• encapsulamento de legado• permite evolução incremental do legado
REST= +ULCODC$SSLayered System no Alexandria
REST= +LCODC$SS U
• Extensibilidade• Simplificação do client
• Visibilidade
Code-on-demand
• widgets dos data-entries• no futuro, o console também será instanciado assim• é um elemento importante do REST que foi esquecido por um tempo pela nossa arquitetura
REST= +ULCODC$SSCode-on-demand no Alexandria
REST= +LCODC$SS U
• Simplificação pela generalidade• Visibilidade• Desacoplamento• Evolvabilidade
• Performance percebida pelo usuário• Restrita a dados com granularidade larga
Uniform interface
REST=
niform interface no Alexandria
+LCODC$SS
U
Uresource identification
URIuniversal resource identifier
Uresource identification
/:tipo_recurso/:id
Uresource identification
http://editorial.api.abril.com.br/materia/dicas
http://editorial.api.abril.com.br/materia/ac23657fg
http://bebe.abril.com.br/materia/ac23657fg
Uresources
Uresources
{ "tipo_recurso" : "materia", "link" : [ { "href" : "http://editorial.api.abril.com.br/materia/4f0dea5a1e13694", "rel" : "self", "type" : "application/json" }, { "href" : "http://editorial.api.abril.com.br/materias", "rel" : "materias", "type" : "application/json" } ], "id" : "http://editorial.api.abril.com.br/materia/4f0dea5a1e13694", "slug" : "o-quintal-da-realeza", "marca" : "viajeaqui", "status" : "disponivel", "descricao_conteudo" : "O quintal da realeza", "fonte" : "viajeaqui",
(continua)
Uresources "criacao" : { "usuario" : "Miguel Icassatti", "data" : "2012-01-11T18:00:26-02:00" }, "ultima_atualizacao" : { "usuario" : "Miguel Icassatti", "data" : "2012-01-19T16:47:18-02:00" }, "disponibilizacao" : { "usuario" : "Miguel Icassatti", "data" : "2012-01-11T18:05:44-02:00" }, "conteudos_relacionados" : [ { "slug" : "4f0deb759d0a73284d00001e", "link" : { "href" : "http://editorial.api.abril.com.br/galerias_multimidia/4f0deb759d0a73284", "rel" : "galeria_multimidia", "type" : "application/json" }, "preview" : "http://imgms.alexandria.abril.com.br/10/thumbnail-240x240-a1.jpeg", "tipo_recurso" : "galeria_multimidia", "fonte" : "viajeaqui", "credito" : "(não especificado)", "descricao" : "Fotos das atrações e estabelecimentos de Windsor, cidade da Inglaterra", "id" : "http://editorial.api.abril.com.br/galerias_multimidia/4f0deb759d0a73284d00001e", "titulo" : "Especial viajeaqui em Londres" } ],
(continua)
Uresources
"rotulos_controlados" : [ "Londres2012" ], "tags" : [ "Londres", "restaurantes", "atrações" ], "editorias" : [ "Matérias" ], "categorias" : [ "Turismo e Lazer", "Turismo e Lazer::Cidade", "Turismo e Lazer::PaÃs" ], "autor" : "Miguel Icassatti", "titulo" : "O quintal da realeza", "chapeu" : "Windsor", "subtitulo" : "Nossa viagem pela Inglaterra tem a primeira parada na histórica Windsor.", "corpo" : "<p>Localizada à s margens do rio Tâmisa, que corta também Londres, a cidade de Windsor já foi sede da monarquia britânica.</p>"}
Urepresentations
JSON
Urepresentations
e um tiquinho assim de XML
ou melhor,de application/opensearchdescription+xml
Urepresentations
<?xml version="1.0" encoding="UTF-8"?><OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:grafo="http://socialcore.api.abril.com.br/grafo/busca">
<ShortName>Buscar relacionamentos</ShortName> <Description>Busca de relacionamentos no grafo</Description>
<Url type="application/json" template="http://socialcore.api.abril.com.br/grafo/busca?usuario={grafo:usuario?}&tipo={grafo:tipo}"/>
<Query role="example" title="Exemplo de valores dos parâmetros" grafo:usuario="id do usuario" grafo:tipo="segue |seguido_por " />
</OpenSearchDescription>
Uhypermedia
image from the book Rest in Practice (by Jim Webber) (pag. 14)
Uhypermedia
Exercício: criar uma atividade de um usuário no site.
Você só sabe o entrypoint:
http://socialcore.api.abril.com.br
Uhypermedia
POST http://socialcore.api.abril.com.br/Accept: application/json
Uhypermedia
POST???
Uhypermedia
HTTP/1.1 405 Method Not AllowedAllow: GET
Uhypermedia
GET http://socialcore.api.abril.com.br/Accept: application/json
UhypermediaHTTP/1.1 200 OKContent-Type: application/json; charset=utf-8{ "titulo": "socialcore", "link": [ { "href": "http://socialcore.api.abril.com.br/", "rel": "self", "type": "application/json" }, { "href": "http://socialcore.api.abril.com.br/atividade", "rel": "atividade", "type": "application/json" }, { "href": "http://socialcore.api.abril.com.br/grafo", "rel": "grafo", "type": "application/json" } ]}
Uhypermedia
GET http://socialcore.api.abril.com.br/atividadeAccept: application/json
Uhypermedia
HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8{ "titulo": "Entry Point de Atividades", "link": [ { "href": "http://socialcore.api.abril.com.br/atividade/template", "rel": "template", "type": "application/json" }, { "href": "http://socialcore.api.abril.com.br/atividade/busca/descritor", "rel": "search", "type": "application/opensearchdescription+xml" }, { "href": "http://socialcore.api.abril.com.br/atividade/stat/descritor", "rel": "stat", "type": "application/opensearchdescription+xml" } ]}
Uhypermedia
GET http://socialcore.api.abril.com.br/atividade/templateAccept: application/json
Uhypermedia
HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8{ "atividade": { "app": "", "created_at": "", "usuario": "", "tipo": "", "objeto": { "tipo": "" }, "resultado": { "tipo": "" } },
(continua)
Uhypermedia
"link": [ { "href": "http://socialcore.api.abril.com.br/atividade", "rel": "atividade", "type": "application/json" }, { "href": "http://socialcore.api.abril.com.br/atividade/busca/descritor", "rel": "search", "type": "application/opensearchdescription+xml" }, { "href": "http://socialcore.api.abril.com.br/atividade/stat/descritor", "rel": "stat", "type": "application/opensearchdescription+xml" } ]}
UhypermediaPOST http://socialcore.api.abril.com.br/atividadeAccept: application/jsonContent-‐Type: application/json; charset=utf-‐8Authentication: Basic 37rnx9w87rjdw87gri
{ "atividade": { "app": "http://aapg.api.abril.com.br/produtos/1", "created_at": 1325086429, "tipo": "comentar", "objeto": { "descricao": "Titulo da materia", "id": "http://veja.abril.com.br/noticia/economia/confianca-da", "tipo": "materia" }, "resultado": { "corpo": "otima materia", "id": "http://veja.abril.com.br/noticia/economia/confianca-da/comments/1", "tipo": "comentario" } }}
Uhypermedia
HTTP/1.1 422 Unprocessable EntityContent-Type: application/json; charset=utf-8{ "tipo_recurso":"erro", "atividade":{ "usuario":"", }, "erros":[ {"atributo":"usuario","mensagem":["é obrigatório"]} ]}
UhypermediaPOST http://socialcore.api.abril.com.br/atividadeAccept: application/jsonContent-‐Type: application/json; charset=utf-‐8Authentication: Basic 37rnx9w87rjdw87gri
{ "atividade": { "app": "http://aapg.api.abril.com.br/produtos/1", "created_at": 1325086429, "usuario": "http://aapg.api.abril.com.br/usuarios/2", "tipo": "comentar", "objeto": { "descricao": "Titulo da materia", "id": "http://veja.abril.com.br/noticia/economia/confianca-da", "tipo": "materia" }, "resultado": { "corpo": "otima materia", "id": "http://veja.abril.com.br/noticia/economia/confianca-da/comments/1", "tipo": "comentario" } }}
Uhypermedia
HTTP/1.1 201 CreatedContent-Type: application/json; charset=utf-8Location: http://socialcore.api.abril.com.br/atividade/0922307
\o/
Uapplication protocol
HTTPstatus codes
representation metadataresource metadata
control data
Lições aprendidas
pontos importantes em performance
clientorigin server
• performance dos connectors• non-blocking HTTP clients
• cache local• middleware architecture• libs padronizadas
• short stacks• evented servers• libs padronizadas
• good TTL strategy• middleware architecture
• caches• HTTP plumbing
• Lei de Postel• Seja conservador no que faz, seja liberal no que você aceita dos outros
• REST é uma arquitetura de longo prazo
• Defenda com todas as suas forças:• seus metadados (recursos)• sua interface
• Documentação é essencial
• Independência de desenvolvimento dos nós tem suas desvantagens
• medir/monitorar o desempenho é importantíssimo
Assumimos que nossa arquitetura está válida.
necessidadesatendidas
custoaceitável + * ß
MTRH
mas...
e quando REST não for suficiente?
não use REST
Os responsáveis
• bit.ly/abril_qcon_refs
• engineering.abril.com.br
• talleye.com
• digital.abril.com.br
Obrigado!