SlideShare a Scribd company logo
1 of 59
Criando APIs - Usando Rails
Fernando Kakimoto
Desenvolvedor @ ThoughtWorks
O que é uma API mesmo?
Application Programming Interface
Biblioteca que inclui especificações para rotinas,
estruturas de dados, objetos, classes e variáveis
Características de boas APIs
 Fácil de aprender e memorizar
 Dificilmente usada de maneira errada
 Minimalista
 Completa
Tópicos para hoje
 REST
 Consistência
 Versionamento
 Segurança
REST
REpresentational State Transfer
Um padrão arquitetural para sistemas hipermídias
distribuídos
REST
 URL base
 Tipo de mídia
 Operações (Método HTTP)
REST
GET
https://api.twitter.com/1.1/statuses/menti
ons_timeline.json
REST
GET
https://api.twitter.com/1.1/statuses/menti
ons_timeline.json
URL base
REST
GET
https://api.twitter.com/1.1/statuses/menti
ons_timeline.jsonTipo de mídia
REST
GET
https://api.twitter.com/1.1/statuses/menti
ons_timeline.json
Método
2 URLs base por recurso
• GET /tickets - recupera conjunto de tickets
• GET /tickets/12 - recupera o ticket #12
• POST /tickets - cria um novo ticket
• PUT /tickets/12 - atualiza ticket #12
• DELETE /tickets/12 - remove ticket #12
Restrições REST
 Cliente-Servidor
 Stateless
 Cacheable
 Sistema em camadas
 Interface Uniforme
API RESTful
API implementada usando
princípios HTTP e REST
> nandokakimoto@Development$ rails new blog
> nandokakimoto@blog$ rails generate scaffold Post name:string title:string
content:text
> nandokakimoto@blog$ rake routes
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
Consistência
Métodos Safe
Métodos que nunca modificam um
recurso
Dados não devem ser alterados como resultado de uma requisição GET
Métodos Idempotentes
Métodos com o mesmo resultado
mesmo que requisição seja repetida
diversas vezes
POST é o único método não idempotente
Código de Resposta
Respostas HTTP padronizam como
informar o cliente sobre o resultado da
sua requisição
Código de Resposta
 1xx - Informacional
 2xx - Sucesso
 3xx - Redirecionamento
 4xx - Erro de cliente
 5xx - Erro de servidor
> nandokakimoto@blog$ curl -v http://localhost:3000/posts.json
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /posts.json HTTP/1.1
<
< HTTP/1.1 200 OK
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
[{"content": "Melhor evento ever <3 <3 <3", "created_at": "2013-09-03T02:12:26Z",
"id": 1, "name": "Frevo on Rails", "title": "Evento 14 Setembro", "updated_at": "2013-
09-03T02:12:26Z"}]
> nandokakimoto@blog$ curl -v -d "post[name]=Geek Night&post[title]=Scala
Dojo&post[content]=Come and learn Scala" http://localhost:3000/posts.json
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /posts.json HTTP/1.1
> Host: localhost:3000
<
< HTTP/1.1 201 Created
< Location: http://localhost:3000/posts/2
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
{"content": "Come and learn Scala", "created_at": "2013-09-04T01:19:33Z", "id”: 2,
"name": "Geek Night", "title":"Scala Dojo", "updated_at": "2013-09-04T01:19:33Z"}
> nandokakimoto@blog$ curl -v -d "post[name]=Geek
Night&post[content]=Come and learn Scala" http://localhost:3000/posts.json
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /posts.json HTTP/1.1
> Host: localhost:3000
> Content-Length: 56
>
< HTTP/1.1 422
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 28
{"title":["can't be blank"]}
Versionamento
Versionamento
Sempre versione a sua API
Diferentes opniões sobre se a versão deve estar na URL ou no
cabeçalho
Versionamento
 Versionist - https://github.com/bploetz/versionist
 RocketPants - https://github.com/filtersquad/rocket_pants
config/routes.rb
> nandokakimoto@blog$ rake routes
(…)
GET /api/v1/products(.:format) api/v1/posts#index
POST /api/v1/products(.:format) api/v1/posts#create
GET /api/v1/products/new(.:format) api/v1/posts#new
GET /api/v1/products/:id/edit(.:format) api/v1/posts#edit
GET /api/v1/products/:id(.:format) api/v1/posts#show
PUT /api/v1/products/:id(.:format) api/v1/posts#update
DELETE /api/v1/products/:id(.:format) api/v1/posts#destroy
app/controllers/api/v1/posts_controller.rb
> nandokakimoto@blog$ curl -v http://localhost:3000/api/v1/posts.json
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/v1/posts HTTP/1.1
> Host: localhost:3000
<
< HTTP/1.1 200 OK
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 330
[{"content": "Melhor evento ever <3 <3 <3", "created_at":"2013-09-03T02:12:26Z",
"id": 1, "name": "Frevo on Rails", "title": "Evento 14 Setembro", "updated_at": "2013-
09-03T02:12:26Z"}, {"content": "Come and learn Scala", "created_at": "2013-09-
04T01:19:33Z", "id": 2, "name": "Geek Night", "title": "Scala Dojo", "updated_at":
"2013-09-04T01:19:33Z"}]
> nandokakimoto@blog$ curl -v http://localhost:3000/api/v1/posts/15.json
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/v1/posts/15.json HTTP/1.1
> Host: localhost:3000
>
< HTTP/1.1 404 Not Found
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 1
<
Versionamento
Novo Requisito
Mostrar apenas id, nome e título do post
config/routes.rb
> nandokakimoto@blog$ rake routes
(…)
GET /api/v2/posts(.:format) api/v2/posts#index
POST /api/v2/posts(.:format) api/v2/posts#create
GET /api/v2/posts/new(.:format) api/v2/posts#new
GET /api/v2/posts/:id/edit(.:format) api/v2/posts#edit
GET /api/v2/posts/:id(.:format) api/v2/posts#show
PUT /api/v2/posts/:id(.:format) api/v2/posts#update
DELETE /api/v2/posts/:id(.:format) api/v2/posts#destroy
app/controllers/api/v2/posts_controller.rb
RABL
RABL (Ruby API Builder Language) consiste num sistema de
template RAILS para geração de JSON
app/views/api/v2/show.rabl.json
app/views/api/v2/index.rabl.json
> nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/v2/posts HTTP/1.1
> Host: localhost:3000
<
< HTTP/1.1 200 OK
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 113
[{"id":1,"name":"Frevo on Rails","title":"Evento 14 Setembro"},{"id”:2,"name":"Geek
Night","title":"Scala Dojo"}]
Segurança
HTTP Basic Authentication
 Solução mais simples
 Fácil de implementar
 Maioria dos clientes suportam
app/controllers/api/v2/posts_controller.rb
> nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/v2/posts HTTP/1.1
> Host: localhost:3000
<
< HTTP/1.1 200 OK
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 113
[{"id":1,"name":"Frevo on Rails","title":"Evento 14 Setembro"},{"id”:2,"name":"Geek
Night","title":"Scala Dojo"}]
> nandokakimoto@blog$ curl -v -d "post[name]=RubyConf&post[title]=RubyConf
Details&post[content]=RubyConf was awesome"
http://localhost:3000/api/v2/posts.json
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /api/v2/posts.json HTTP/1.1
> Host: localhost:3000
> Content-Length: 82
>
< HTTP/1.1 401 Unauthorized
< WWW-Authenticate: Basic realm="Application"
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 27
<
HTTP Basic: Access denied.
> nandokakimoto@blog$ curl -v -d "post[name]=RubyConf&post[title]=RubyConf
Details&post[content]=RubyConf was awesome"
http://localhost:3000/api/v2/posts.json -u "admin:secret"
* Connected to localhost (127.0.0.1) port 3000 (#0)
* Server auth using Basic with user 'admin'
> POST /api/v2/posts.json HTTP/1.1
> Authorization: Basic YWRtaW46c2VjcmV0
> Host: localhost:3000
> Content-Length: 83
>
< HTTP/1.1 201 Created
< Location: http://localhost:3000/api/v2/posts/3
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 159
{"id":3,"name":"RubyConf","title":"RubyConf Details”}
Token de Acesso
 Maior entropia
 Token é salvo no servidor
 Data de expiração
> nandokakimoto@blog$ rails g model api_key access_token
invoke active_record
create db/migrate/20130907211645_create_api_keys.rb
create app/models/api_key.rb
invoke test_unit
create test/unit/api_key_test.rb
create test/fixtures/api_keys.yml
app/model/api_key.rb
app/controllers/api/v2/posts_controller.rb
> nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts
curl -v http://localhost:3000/api/v2/posts
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/v2/posts HTTP/1.1
> Host: localhost:3000
>
< HTTP/1.1 401 Unauthorized
< WWW-Authenticate: Token realm="Application"
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 27
<
HTTP Token: Access denied.
> nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts -H
'Authorization: Token token=”8219a125816b331d0e478eeab566bf7c”'
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/v2/posts HTTP/1.1
> Host: localhost:3000
> Authorization: Token token="8219a125816b331d0e478eeab566bf7c"
>
< HTTP/1.1 200 OK
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27)
< Content-Length: 168
[{"id":1,"name":"Frevo on Rails","title":"Evento 14 Setembro"},{"id":2,"name":"Geek
Night","title":"Scala Dojo"},{"id":3,"name":"RubyConf","title":"RubyConf Details"}]
OAuth
“An open protocol to allow secure
authorization in a simple and
standard method from web, mobile
and desktop application”
- http://oauth.net -
OAuth
 Doorkeeper
 Oauth2
Tópicos Futuros
 Filtros, ordenação, busca
 Paginação
 Documentação
 Limitação de uso
Pra Terminar
API é a intefarce de usuário para os
desenvolvedores
Trabalhe para garantir que ela seja funcional e prazerosa de usar

More Related Content

What's hot

Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 

What's hot (20)

Failsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageFailsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo Homepage
 
Plack at OSCON 2010
Plack at OSCON 2010Plack at OSCON 2010
Plack at OSCON 2010
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Rack
RackRack
Rack
 
Top Node.js Metrics to Watch
Top Node.js Metrics to WatchTop Node.js Metrics to Watch
Top Node.js Metrics to Watch
 
Securing Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp VaultSecuring Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp Vault
 
bootstrapping containers with confd
bootstrapping containers with confdbootstrapping containers with confd
bootstrapping containers with confd
 
Nomad + Flatcar: a harmonious marriage of lightweights
Nomad + Flatcar: a harmonious marriage of lightweightsNomad + Flatcar: a harmonious marriage of lightweights
Nomad + Flatcar: a harmonious marriage of lightweights
 
Migrating a large code-base to containers by Doug Johnson and Jonathan Lozins...
Migrating a large code-base to containers by Doug Johnson and Jonathan Lozins...Migrating a large code-base to containers by Doug Johnson and Jonathan Lozins...
Migrating a large code-base to containers by Doug Johnson and Jonathan Lozins...
 
About Node.js
About Node.jsAbout Node.js
About Node.js
 
A complete guide to Node.js
A complete guide to Node.jsA complete guide to Node.js
A complete guide to Node.js
 
ITB2019 NGINX Overview and Technical Aspects - Kevin Jones
ITB2019 NGINX Overview and Technical Aspects - Kevin JonesITB2019 NGINX Overview and Technical Aspects - Kevin Jones
ITB2019 NGINX Overview and Technical Aspects - Kevin Jones
 
Introducing the Seneca MVP framework for Node.js
Introducing the Seneca MVP framework for Node.jsIntroducing the Seneca MVP framework for Node.js
Introducing the Seneca MVP framework for Node.js
 
Consul - service discovery and others
Consul - service discovery and othersConsul - service discovery and others
Consul - service discovery and others
 
Microservices with SenecaJS (part 2)
Microservices with SenecaJS (part 2)Microservices with SenecaJS (part 2)
Microservices with SenecaJS (part 2)
 
Plone 5 and machine learning
Plone 5 and machine learningPlone 5 and machine learning
Plone 5 and machine learning
 
201904 websocket
201904 websocket201904 websocket
201904 websocket
 
泣かないAppEngine開発
泣かないAppEngine開発泣かないAppEngine開発
泣かないAppEngine開発
 
Introduction to rest.li
Introduction to rest.liIntroduction to rest.li
Introduction to rest.li
 

Similar to Construindo APIs Usando Rails

[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
CODE BLUE
 

Similar to Construindo APIs Usando Rails (20)

[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
 
RoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails example
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rack
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
Intro to fog and openstack jp
Intro to fog and openstack jpIntro to fog and openstack jp
Intro to fog and openstack jp
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
RSS Like A Ninja
RSS Like A NinjaRSS Like A Ninja
RSS Like A Ninja
 
Rapid JCR Applications Development with Sling
Rapid JCR Applications Development with SlingRapid JCR Applications Development with Sling
Rapid JCR Applications Development with Sling
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of users
 
IBM dwLive, "Internet & HTTP - 잃어버린 패킷을 찾아서..."
IBM dwLive, "Internet & HTTP - 잃어버린 패킷을 찾아서..."IBM dwLive, "Internet & HTTP - 잃어버린 패킷을 찾아서..."
IBM dwLive, "Internet & HTTP - 잃어버린 패킷을 찾아서..."
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
LF_APIStrat17_REST API Microversions
LF_APIStrat17_REST API Microversions LF_APIStrat17_REST API Microversions
LF_APIStrat17_REST API Microversions
 
Ruby MVC from scratch with Rack
Ruby MVC from scratch with RackRuby MVC from scratch with Rack
Ruby MVC from scratch with Rack
 

Recently uploaded

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Construindo APIs Usando Rails

  • 1. Criando APIs - Usando Rails Fernando Kakimoto Desenvolvedor @ ThoughtWorks
  • 2. O que é uma API mesmo? Application Programming Interface Biblioteca que inclui especificações para rotinas, estruturas de dados, objetos, classes e variáveis
  • 3.
  • 4.
  • 5. Características de boas APIs  Fácil de aprender e memorizar  Dificilmente usada de maneira errada  Minimalista  Completa
  • 6. Tópicos para hoje  REST  Consistência  Versionamento  Segurança
  • 7. REST REpresentational State Transfer Um padrão arquitetural para sistemas hipermídias distribuídos
  • 8. REST  URL base  Tipo de mídia  Operações (Método HTTP)
  • 13. 2 URLs base por recurso • GET /tickets - recupera conjunto de tickets • GET /tickets/12 - recupera o ticket #12 • POST /tickets - cria um novo ticket • PUT /tickets/12 - atualiza ticket #12 • DELETE /tickets/12 - remove ticket #12
  • 14. Restrições REST  Cliente-Servidor  Stateless  Cacheable  Sistema em camadas  Interface Uniforme
  • 15. API RESTful API implementada usando princípios HTTP e REST
  • 16. > nandokakimoto@Development$ rails new blog > nandokakimoto@blog$ rails generate scaffold Post name:string title:string content:text > nandokakimoto@blog$ rake routes posts GET /posts(.:format) posts#index POST /posts(.:format) posts#create new_post GET /posts/new(.:format) posts#new edit_post GET /posts/:id/edit(.:format) posts#edit post GET /posts/:id(.:format) posts#show PUT /posts/:id(.:format) posts#update DELETE /posts/:id(.:format) posts#destroy
  • 18.
  • 19. Métodos Safe Métodos que nunca modificam um recurso Dados não devem ser alterados como resultado de uma requisição GET
  • 20. Métodos Idempotentes Métodos com o mesmo resultado mesmo que requisição seja repetida diversas vezes POST é o único método não idempotente
  • 21. Código de Resposta Respostas HTTP padronizam como informar o cliente sobre o resultado da sua requisição
  • 22. Código de Resposta  1xx - Informacional  2xx - Sucesso  3xx - Redirecionamento  4xx - Erro de cliente  5xx - Erro de servidor
  • 23. > nandokakimoto@blog$ curl -v http://localhost:3000/posts.json * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /posts.json HTTP/1.1 < < HTTP/1.1 200 OK < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) [{"content": "Melhor evento ever <3 <3 <3", "created_at": "2013-09-03T02:12:26Z", "id": 1, "name": "Frevo on Rails", "title": "Evento 14 Setembro", "updated_at": "2013- 09-03T02:12:26Z"}]
  • 24. > nandokakimoto@blog$ curl -v -d "post[name]=Geek Night&post[title]=Scala Dojo&post[content]=Come and learn Scala" http://localhost:3000/posts.json * Connected to localhost (127.0.0.1) port 3000 (#0) > POST /posts.json HTTP/1.1 > Host: localhost:3000 < < HTTP/1.1 201 Created < Location: http://localhost:3000/posts/2 < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) {"content": "Come and learn Scala", "created_at": "2013-09-04T01:19:33Z", "id”: 2, "name": "Geek Night", "title":"Scala Dojo", "updated_at": "2013-09-04T01:19:33Z"}
  • 25. > nandokakimoto@blog$ curl -v -d "post[name]=Geek Night&post[content]=Come and learn Scala" http://localhost:3000/posts.json * Connected to localhost (127.0.0.1) port 3000 (#0) > POST /posts.json HTTP/1.1 > Host: localhost:3000 > Content-Length: 56 > < HTTP/1.1 422 < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 28 {"title":["can't be blank"]}
  • 27.
  • 28. Versionamento Sempre versione a sua API Diferentes opniões sobre se a versão deve estar na URL ou no cabeçalho
  • 29.
  • 30. Versionamento  Versionist - https://github.com/bploetz/versionist  RocketPants - https://github.com/filtersquad/rocket_pants
  • 32. > nandokakimoto@blog$ rake routes (…) GET /api/v1/products(.:format) api/v1/posts#index POST /api/v1/products(.:format) api/v1/posts#create GET /api/v1/products/new(.:format) api/v1/posts#new GET /api/v1/products/:id/edit(.:format) api/v1/posts#edit GET /api/v1/products/:id(.:format) api/v1/posts#show PUT /api/v1/products/:id(.:format) api/v1/posts#update DELETE /api/v1/products/:id(.:format) api/v1/posts#destroy
  • 34. > nandokakimoto@blog$ curl -v http://localhost:3000/api/v1/posts.json * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /api/v1/posts HTTP/1.1 > Host: localhost:3000 < < HTTP/1.1 200 OK < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 330 [{"content": "Melhor evento ever <3 <3 <3", "created_at":"2013-09-03T02:12:26Z", "id": 1, "name": "Frevo on Rails", "title": "Evento 14 Setembro", "updated_at": "2013- 09-03T02:12:26Z"}, {"content": "Come and learn Scala", "created_at": "2013-09- 04T01:19:33Z", "id": 2, "name": "Geek Night", "title": "Scala Dojo", "updated_at": "2013-09-04T01:19:33Z"}]
  • 35. > nandokakimoto@blog$ curl -v http://localhost:3000/api/v1/posts/15.json * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /api/v1/posts/15.json HTTP/1.1 > Host: localhost:3000 > < HTTP/1.1 404 Not Found < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 1 <
  • 36. Versionamento Novo Requisito Mostrar apenas id, nome e título do post
  • 38. > nandokakimoto@blog$ rake routes (…) GET /api/v2/posts(.:format) api/v2/posts#index POST /api/v2/posts(.:format) api/v2/posts#create GET /api/v2/posts/new(.:format) api/v2/posts#new GET /api/v2/posts/:id/edit(.:format) api/v2/posts#edit GET /api/v2/posts/:id(.:format) api/v2/posts#show PUT /api/v2/posts/:id(.:format) api/v2/posts#update DELETE /api/v2/posts/:id(.:format) api/v2/posts#destroy
  • 40. RABL RABL (Ruby API Builder Language) consiste num sistema de template RAILS para geração de JSON
  • 42. > nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /api/v2/posts HTTP/1.1 > Host: localhost:3000 < < HTTP/1.1 200 OK < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 113 [{"id":1,"name":"Frevo on Rails","title":"Evento 14 Setembro"},{"id”:2,"name":"Geek Night","title":"Scala Dojo"}]
  • 43.
  • 45. HTTP Basic Authentication  Solução mais simples  Fácil de implementar  Maioria dos clientes suportam
  • 47. > nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /api/v2/posts HTTP/1.1 > Host: localhost:3000 < < HTTP/1.1 200 OK < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 113 [{"id":1,"name":"Frevo on Rails","title":"Evento 14 Setembro"},{"id”:2,"name":"Geek Night","title":"Scala Dojo"}]
  • 48. > nandokakimoto@blog$ curl -v -d "post[name]=RubyConf&post[title]=RubyConf Details&post[content]=RubyConf was awesome" http://localhost:3000/api/v2/posts.json * Connected to localhost (127.0.0.1) port 3000 (#0) > POST /api/v2/posts.json HTTP/1.1 > Host: localhost:3000 > Content-Length: 82 > < HTTP/1.1 401 Unauthorized < WWW-Authenticate: Basic realm="Application" < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 27 < HTTP Basic: Access denied.
  • 49. > nandokakimoto@blog$ curl -v -d "post[name]=RubyConf&post[title]=RubyConf Details&post[content]=RubyConf was awesome" http://localhost:3000/api/v2/posts.json -u "admin:secret" * Connected to localhost (127.0.0.1) port 3000 (#0) * Server auth using Basic with user 'admin' > POST /api/v2/posts.json HTTP/1.1 > Authorization: Basic YWRtaW46c2VjcmV0 > Host: localhost:3000 > Content-Length: 83 > < HTTP/1.1 201 Created < Location: http://localhost:3000/api/v2/posts/3 < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 159 {"id":3,"name":"RubyConf","title":"RubyConf Details”}
  • 50. Token de Acesso  Maior entropia  Token é salvo no servidor  Data de expiração
  • 51. > nandokakimoto@blog$ rails g model api_key access_token invoke active_record create db/migrate/20130907211645_create_api_keys.rb create app/models/api_key.rb invoke test_unit create test/unit/api_key_test.rb create test/fixtures/api_keys.yml
  • 54. > nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts curl -v http://localhost:3000/api/v2/posts * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /api/v2/posts HTTP/1.1 > Host: localhost:3000 > < HTTP/1.1 401 Unauthorized < WWW-Authenticate: Token realm="Application" < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 27 < HTTP Token: Access denied.
  • 55. > nandokakimoto@blog$ curl -v http://localhost:3000/api/v2/posts -H 'Authorization: Token token=”8219a125816b331d0e478eeab566bf7c”' * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /api/v2/posts HTTP/1.1 > Host: localhost:3000 > Authorization: Token token="8219a125816b331d0e478eeab566bf7c" > < HTTP/1.1 200 OK < Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-06-27) < Content-Length: 168 [{"id":1,"name":"Frevo on Rails","title":"Evento 14 Setembro"},{"id":2,"name":"Geek Night","title":"Scala Dojo"},{"id":3,"name":"RubyConf","title":"RubyConf Details"}]
  • 56. OAuth “An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop application” - http://oauth.net -
  • 58. Tópicos Futuros  Filtros, ordenação, busca  Paginação  Documentação  Limitação de uso
  • 59. Pra Terminar API é a intefarce de usuário para os desenvolvedores Trabalhe para garantir que ela seja funcional e prazerosa de usar

Editor's Notes

  1. http://www4.in.tum.de/~blanchet/api-design.pdf
  2. If there&apos;s one thing that has gained wide adoption, it&apos;s RESTful principles. These were first introduced by Roy Felding in Chapter 5 of his dissertation on network based software architectures. The key principles of REST involve separating your API into logical resources. These resources are manipulated using HTTP requests where the method (GET, POST, PUT, PATCH, DELETE) has specific meaning.A resource should be nouns (not verbs!) that make sense from the perspective of the API consume.REST is a simple way to organize interactions between independent systems
  3. It is a collection of resources, with four defined aspects
  4. Client–server:A uniform interface separates clients from servers. This separation of concerns means that, for example, clients are not concerned with data storage, which remains internal to each server, so that the portability of client code is improved. Servers are not concerned with the user interface or user state, so that servers can be simpler and more scalable. Servers and clients may also be replaced and developed independently, as long as the interface between them is not altered.Stateless: The client–server communication is further constrained by no client context being stored on the server between requests. Each request from any client contains all of the information necessary to service the request, and any session state is held in the client.Cacheable: As on the World Wide Web, clients can cache responses. Responses must therefore, implicitly or explicitly, define themselves as cacheable, or not, to prevent clients reusing stale or inappropriate data in response to further requests. Well-managed caching partially or completely eliminates some client–server interactions, further improving scalability and performance.Layered system: A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. Intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. They may also enforce security policies.Uniform interface:The uniform interface between clients and servers, discussed below, simplifies and decouples the architecture, which enables each part to evolve independently. The four guiding principles of this interface are detailed below.
  5. To prevent an API consumer from having to hit the API again for an updated representation, have the API return the updated (or created) representation as part of the response.
  6. Status codes tell the client application what it needs to do with the response in general terms. For example, if your API returns a 401 you know you need a logged in user. If the API returns a 403 you know the user you’re working with doesn’t have sufficient authorization. If the API returns a 418 you know that the API is telling you it’s a teapot and was probably written by knobs.Validation error in Rails = 422 unprocessableentityDelete in Rails = 204 No Content
  7. Just like an HTML error page shows a useful error message to a visitor, an API should provide a useful error message in a known consumable format. The representation of an error should be no different than the representation of any resource, just with its own set of fields.API that return 200 but error in the response code.
  8. Always version your API. Versioning helps you iterate faster and prevents invalid requests from hitting updated endpoints. It also helps smooth over any major API version transitions as you can continue to offer old API versions for a period of time.There are mixed opinions around whether an API version should be included in the URL or in a header. Academically speaking, it should probably be in a header. However, the version needs to be in the URL to ensure browser explorability of the resources across versions (remember the API requirements specified at the top of this post?).
  9. https://blog.apigee.com/detail/restful_api_design_tips_for_versioning
  10. https://blog.apigee.com/detail/restful_api_design_tips_for_versioning
  11. A RESTful API should be stateless. This means that request authentication should not depend on cookies or sessions. Instead, each request should come with some sort authentication credentials.
  12. HTTP Basic authentication (BA) implementation is the simplest technique for enforcing access controls to web resources because it doesn&apos;t require cookies, session identifier and login pages. Rather, HTTP Basic authentication uses static, standard HTTP headers which means that no handshakes have to be done in anticipation.One thing to watch out for is that the credentials are sent as clear text so we should be sure to use a secure connection or maybe a digest connection.
  13. API keys/secrets are usually a long series of random characters that are difficult to guess. Username/password are typically much smaller in length, use common words, are generally insecure, and can be subject to brute force and dictionary attacks.
  14. It provides a much needed solution for security web APIs without requiring users to share their usernames and passwordsOAuth provides a mechanism for users to grant access to private data without sharing their private credentials (username/password). Many sites have started enabling APIs to use OAuth because of its security and standard set of libraries.