SlideShare a Scribd company logo
BUILDINg BETTER
WITH railS
Devils Tower, WY
web APIS
@caikeCarlos Souza
Code School
codeschool.com
tryruby.org
railsforzombies.org
perfect
rails web app
Deadline
Budget
Features
Tests
“We need a snappier
experience”
“We’ve detected the majority
of our visitors come from
mobile devices. 



We need to launch a native app

as soon as possible!”
“Does our web app
expose an API ?”
• Routes
• CONNEG
• AUTH
• VERSION
• Tests
endpoints, resources and
url-to-controller mappings
ROUTES
URLs are very important
/gists
/gists/public
/gists/starred
resources :projects
GET

POST

PATCH (PUT) 

DELETE
!
!
...
Projects#index
Projects#create
Projects#show
Projects#update
Projects#destroy
...
paths methods actions
/projects
/projects/:id
resources :projects
paths
/projects/archived

/projects/:id/archive

/projects
/projects/:id
?????
resources :projects
end
end
end
member do	
post 'archive'


collection do	
get 'archived'
do


!
get 'active'	
get 'suspended'	
!
!
!
post 'activate'	
post 'suspend'	
!
!
resources :projects
end
end
end
do
member do	
post 'archive'


collection do	
get 'archived'
post 'create_review'


!
get 'active'	
get 'suspended'	
!
!
!
post 'activate'	
post 'suspend'	
!
!
resources :projects
end
end
end
do
member do	
post 'archive'


collection do	
get 'archived', to: 'archived_projects#index'
, to: 'active_projects#index'
, to: 'suspended_projects#index'
, to: 'archived_projects#create'
, to: 'active_projects#create'
, to: 'suspended_projects#create'
post 'create_review'


!
get 'active'	
get 'suspended'	
!
!
!
post 'activate'	
post 'suspend'	
!
!
resources :projects
end
end
end
do
member do	
post 'archive'


collection do	
get 'archived'
resources :reviews, only: :create
, to: 'archived_projects#index'
, to: 'active_projects#index'
, to: 'suspended_projects#index'
, to: 'archived_projects#create'
, to: 'active_projects#create'
, to: 'suspended_projects#create'
app/controllers/api/projects_controller.rb
module Api	
class ProjectsController < ApplicationController	
def index	
...	
end	
end	
end
ActiveSupport::Inflector.inflections(:en) do |inflect|	
inflect.acronym 'API'	
end
config/initializers/inflections.rb
module API	
class ProjectsController < ApplicationController	
def index	
...	
end	
end	
end
connegcontent negotiation
Client A
API
I’m a Rich Java$cript Application 

and I want JSON!
Hey, I’m an Enterprise Java Application
and I want XML! (Ha Ha, Business!)
¯_(ツ)_/¯
Oi, soy un browser e quiero HTML!
response in JSON
respuesta en HTML
response in XML
Client B
Client C
content negotiation
The process in which client and server
determine the best representation for a response

when many are available.
/projects.json
GET /projects

Accept: application/json
vs.
Rails nicety
Part of the HTTP spec
client requests
responders
extracted out to 

responders gem
in Rails 4.2
module API	
class ProjectsController < ApplicationController	
respond_to :json, :xml	
!
def index	
@projects = Project.all	
!
respond_with(@projects)	
end	
end	
end
calls #to_json
calls #to_xml
respond_to
module API	
class ProjectsController < ApplicationController	
def index	
@projects = Project.recent	
!
respond_to do |format|	
format.json { render json: @projects, status: 200 }	
format.xml { render xml: @projects, status: 200 }	
end	
end	
end	
end
JBuilder
json.content format_content(@message.content)	
json.(@message, :created_at, :updated_at)	
!
json.author do	
json.name @message.creator.name.familiar	
json.url url_for(@message.creator, format: :json)	
end
https://github.com/rails/jbuilder
class ProjectSerializer < ActiveModel::Serializer	
attributes :id, :title, :amount	
!
embed :ids, include: true	
has_many :products	
end
defaults to JSON-API
https://github.com/rails-api/active_model_serializers
ActiveModel::Serializers
module SongsRepresenter	
include Roar::JSON::JsonApi	
name :songs	
!
property :id	
property :title	
end
class SongRepresenter < Roar::Decorator	
include Roar::JSON::JsonApi	
name :songs	
!
property :id	
property :title	
end
https://github.com/apotonick/roar
using Mixins using Decorators
Roar
AUTHenticationpreventing unauthorized access
to protected resources
• Quick and Simple
• Reutilizes existing credentials
• HTTP spec (RFC 2617)
http basic AUTH
http basic AUTH
module API	
class ProjectsController < ApplicationController	
before_action :authenticate_or_request	
!
protected	
!
def authenticate_or_request	
authenticate_or_request_with_http_basic do |user, pwd|	
User.authenticate(user, pwd)	
end	
end	
end	
end
use the -u option
$ curl -I http://carlos:secret@localhost:3000/projects	
!
HTTP/1.1 200 OK	
Content-Type: application/json; charset=utf-8
$ curl -Iu 'carlos:secret' http://localhost:3000/projects	
!
HTTP/1.1 200 OK	
Content-Type: application/json; charset=utf-8
http basic AUTH with curl
• Can easily expire or regenerate tokens.
• Any vulnerability is limited to API access.
• Multiple tokens for each user.
• Different access rules can be implemented.
API
Projects
Forum
Admin
Client A
token based auth
token for the Backpack API
providing the token
Typically available out-of-band
on a user settings page
token for the Digital Ocean API
For security purposes, 

some services will only display
the access token once.
providing the token
token based auth
module API	
class ProjectsController < ApplicationController	
before_action :authenticate_or_request	
!
protected	
!
def authenticate_or_request	
authenticate_or_request_with_http_token do |token, opt|	
User.find_by(auth_token: token)	
end	
end	
end	
end
UUID - Universally Unique Identifier
GENERATING TOKENS
RFC 4122
We can use the Ruby standard library
SecureRandom.uuid
f4ea855f-d303-43e6-bee3-94581c0ecb21
90ab3255-ce33-4022-8349-b7979655b07c
371c760d-2539-41b9-b665-98c255d4c323
...
GENERATING TOKENS
end
def generate_auth_token
.gsub(/-/,'')
end
omits the hyphensSecureRandom.uuid
class User < ActiveRecord::Base	
before_create :set_auth_token	
!
private	
!
def set_auth_token	
return if auth_token.present?

self.auth_token = generate_auth_token	
end	
!
a47a8e54b11c4de5a4a351734c80a14a
9fa8a147b10c4efca3e8592b3a1c2729
823c1c984d504f66a2e6cbb2eb69e842
...
GENERATING TOKENS
$ curl -IH "Authorization: Token token=16d7d6089b8fe0c5e19bfe10bb156832" 	
http://localhost:3000/episodes	
!
HTTP/1.1 200 OK	
Content-Type: application/json; charset=utf-8
use the -H option
token based auth com curl
versioning resources
Version
MAJOR

incompatible changes


MINOR

backwards-compatible changes


PATCH

backwards-compatible bug fixes
http://semver.org/Semantic versioning
Works great for software libraries
V1/V1
feature X, feature Y
/V2
feature X, feature Y,
feature Z
Compatible changes:
• addition of a new format (i.e. JSON, XML )
• addition of a new property on a resource
• renaming of an end-point (use 3xx status code!)
• Only use major version.
• Changes cannot break existing clients.
• No need to bump version on compatible changes.
versioning services
410 Gone
https://www.mnot.net/blog/2012/12/04/api-evolution
“The biggest way to avoid new 

major versions is to make as many 

of your changes backwards-compatible 

as possible”
TESTSautomated verification
API
Unit Tests
testing apis
Not the time nor place to test business logic
API
• Status Code
• Mime Types
• Authentication
WHAT SHOULD WE TEST ?
API
HOW SHOULD WE TEST ?
Requesting endpoints and verifying responses
$ rails g integration_test <doing-something>
testing status code
require 'test_helper'	
!
class ListingProjectsTest < ActionDispatch::IntegrationTest	
setup { host! 'api.example.com' }	
!
test 'returns list of projects' do	
get '/projects'	
assert_equal 200, response.status	
refute_empty response.body	
end	
end
testing status code
require 'test_helper'	
!
class ListingProjectsTest < ActionDispatch::IntegrationTest	
setup { host! 'api.example.com' }	
!
test 'returns list of projects' do	
get '/projects'	
assert_equal 200, response.status	
refute_empty response.body	
end	
end
testing mime types
class ListingProjectsTest < ActionDispatch::IntegrationTest	
setup { host! 'api.example.com' }	


test 'returns projects in JSON' do	
get '/projects', {}, { 'Accept' => Mime::JSON }	
assert_equal Mime::JSON, response.content_type	
end	
test 'returns projects in XML' do	
get '/projects', {}, { 'Accept' => Mime::XML }	
assert_equal Mime::XML, response.content_type	
end	
end
testing mime types
class ListingProjectsTest < ActionDispatch::IntegrationTest	
setup { host! 'api.example.com' }	


test 'returns projects in JSON' do	
get '/projects', {}, { 'Accept' => Mime::JSON }	
assert_equal Mime::JSON, response.content_type	
end	
test 'returns projects in XML' do	
get '/projects', {}, { 'Accept' => Mime::XML }	
assert_equal Mime::XML, response.content_type	
end	
end
class ListingProjectsTest < ActionDispatch::IntegrationTest	
setup { @user = User.create! }	
setup { host! 'api.example.com' }	
!
test 'valid authentication with token' do	
get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}"}	
assert_equal 200, response.status	
assert_equal Mime::JSON, response.content_type	
end	
!
test 'invalid authentication' do	
get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}fake" }	
assert_equal 401, response.status	
end	
end
testing access rules
class ListingProjectsTest < ActionDispatch::IntegrationTest	
setup { @user = User.create! }	
setup { host! 'api.example.com' }	
!
test 'valid authentication with token' do	
get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}"}	
assert_equal 200, response.status	
assert_equal Mime::JSON, response.content_type	
end	
!
test 'invalid authentication' do	
get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}fake" }	
assert_equal 401, response.status	
end	
end
testing access rules
railsapis.codeschool.com
Thank you
BUILDINg BETTER
WITH railS@caikeCarlos Souza
Code School
web APIS
Devils Tower, WY

More Related Content

What's hot

Behavior Driven Development with Cucumber
Behavior Driven Development with CucumberBehavior Driven Development with Cucumber
Behavior Driven Development with CucumberBrandon Keepers
 
The REST And Then Some
The REST And Then SomeThe REST And Then Some
The REST And Then Some
Nordic APIs
 
Introduction to plugin development
Introduction to plugin developmentIntroduction to plugin development
Introduction to plugin development
Caldera Labs
 
Scaling your Android App With Modularization
Scaling your Android App With ModularizationScaling your Android App With Modularization
Scaling your Android App With Modularization
Ben Schwab
 
Test automation with Cucumber-JVM
Test automation with Cucumber-JVMTest automation with Cucumber-JVM
Test automation with Cucumber-JVM
Alan Parkinson
 
Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014
samlown
 
django Forms in a Web API World
django Forms in a Web API Worlddjango Forms in a Web API World
django Forms in a Web API World
Tareque Hossain
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
Sachin G Kulkarni
 
RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
崇之 清水
 
Enter the app era with ruby on rails
Enter the app era with ruby on railsEnter the app era with ruby on rails
Enter the app era with ruby on railsMatteo Collina
 
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsRefactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Tristan Gomez
 
Calabash for iPhone apps
Calabash for iPhone appsCalabash for iPhone apps
Calabash for iPhone apps
Chathura palihakkara
 
Motion Django Meetup
Motion Django MeetupMotion Django Meetup
Motion Django Meetup
Mike Malone
 
Observability and Troubleshooting in Forge
Observability and Troubleshooting in ForgeObservability and Troubleshooting in Forge
Observability and Troubleshooting in Forge
Atlassian
 
Workshop Laravel 5.2
Workshop Laravel 5.2Workshop Laravel 5.2
Workshop Laravel 5.2
Wahyu Rismawan
 
Building Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET CoreBuilding Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET Core
Stormpath
 
Browser-level testing
Browser-level testingBrowser-level testing
Browser-level testing
Martin Kleppmann
 
Serverless observability - a hero's perspective
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspective
Yan Cui
 
REST full API Design
REST full API DesignREST full API Design
REST full API Design
Christian Guenther
 

What's hot (20)

Behavior Driven Development with Cucumber
Behavior Driven Development with CucumberBehavior Driven Development with Cucumber
Behavior Driven Development with Cucumber
 
The REST And Then Some
The REST And Then SomeThe REST And Then Some
The REST And Then Some
 
Introduction to plugin development
Introduction to plugin developmentIntroduction to plugin development
Introduction to plugin development
 
Scaling your Android App With Modularization
Scaling your Android App With ModularizationScaling your Android App With Modularization
Scaling your Android App With Modularization
 
Test automation with Cucumber-JVM
Test automation with Cucumber-JVMTest automation with Cucumber-JVM
Test automation with Cucumber-JVM
 
Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014
 
django Forms in a Web API World
django Forms in a Web API Worlddjango Forms in a Web API World
django Forms in a Web API World
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
 
RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
 
Enter the app era with ruby on rails
Enter the app era with ruby on railsEnter the app era with ruby on rails
Enter the app era with ruby on rails
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsRefactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and Patterns
 
Calabash for iPhone apps
Calabash for iPhone appsCalabash for iPhone apps
Calabash for iPhone apps
 
Motion Django Meetup
Motion Django MeetupMotion Django Meetup
Motion Django Meetup
 
Observability and Troubleshooting in Forge
Observability and Troubleshooting in ForgeObservability and Troubleshooting in Forge
Observability and Troubleshooting in Forge
 
Workshop Laravel 5.2
Workshop Laravel 5.2Workshop Laravel 5.2
Workshop Laravel 5.2
 
Building Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET CoreBuilding Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET Core
 
Browser-level testing
Browser-level testingBrowser-level testing
Browser-level testing
 
Serverless observability - a hero's perspective
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspective
 
REST full API Design
REST full API DesignREST full API Design
REST full API Design
 

Viewers also liked

Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)
Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)
Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)
Dealmaker Media
 
A Local SEO Case Study
A Local SEO Case StudyA Local SEO Case Study
A Local SEO Case Study
Will Fleiss
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing It
Mark
 
What Academia Can Learn from Open Source
What Academia Can Learn from Open SourceWhat Academia Can Learn from Open Source
What Academia Can Learn from Open Source
All Things Open
 
Open Source Systems Administration
Open Source Systems AdministrationOpen Source Systems Administration
Open Source Systems Administration
All Things Open
 
What Does Big Data Really Mean for Your Business?
What Does Big Data Really Mean for Your Business?What Does Big Data Really Mean for Your Business?
What Does Big Data Really Mean for Your Business?
All Things Open
 
The PHP Renaissance
The PHP RenaissanceThe PHP Renaissance
The PHP Renaissance
All Things Open
 
Lessons Learned with Distributed Systems at Bitly
Lessons Learned with Distributed Systems at BitlyLessons Learned with Distributed Systems at Bitly
Lessons Learned with Distributed Systems at Bitly
All Things Open
 
Considerations for Operating an OpenStack Cloud
Considerations for Operating an OpenStack CloudConsiderations for Operating an OpenStack Cloud
Considerations for Operating an OpenStack Cloud
All Things Open
 
All Things Open Opening Keynote
All Things Open Opening KeynoteAll Things Open Opening Keynote
All Things Open Opening Keynote
All Things Open
 
Building the iRODS Consortium
Building the iRODS ConsortiumBuilding the iRODS Consortium
Building the iRODS Consortium
All Things Open
 
The Gurubox Project: Open Source Troubleshooting Tools
The Gurubox Project: Open Source Troubleshooting ToolsThe Gurubox Project: Open Source Troubleshooting Tools
The Gurubox Project: Open Source Troubleshooting Tools
All Things Open
 
Open Source in Healthcare
Open Source in HealthcareOpen Source in Healthcare
Open Source in Healthcare
All Things Open
 
Open Source & The Internet of Things
Open Source & The Internet of ThingsOpen Source & The Internet of Things
Open Source & The Internet of Things
All Things Open
 
The Ember.js Framework - Everything You Need To Know
The Ember.js Framework - Everything You Need To KnowThe Ember.js Framework - Everything You Need To Know
The Ember.js Framework - Everything You Need To Know
All Things Open
 
Stop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case StudyStop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case Study
All Things Open
 
Trademarks and Your Free and Open Source Software Project
Trademarks and Your Free and Open Source Software ProjectTrademarks and Your Free and Open Source Software Project
Trademarks and Your Free and Open Source Software Project
All Things Open
 
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayI Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
All Things Open
 

Viewers also liked (20)

Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)
Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)
Scalability for Startups (Frank Mashraqi, Startonomics SF 2008)
 
A Local SEO Case Study
A Local SEO Case StudyA Local SEO Case Study
A Local SEO Case Study
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing It
 
Go To
Go ToGo To
Go To
 
SEO Case Study: Self Storage Industry
SEO Case Study: Self Storage IndustrySEO Case Study: Self Storage Industry
SEO Case Study: Self Storage Industry
 
What Academia Can Learn from Open Source
What Academia Can Learn from Open SourceWhat Academia Can Learn from Open Source
What Academia Can Learn from Open Source
 
Open Source Systems Administration
Open Source Systems AdministrationOpen Source Systems Administration
Open Source Systems Administration
 
What Does Big Data Really Mean for Your Business?
What Does Big Data Really Mean for Your Business?What Does Big Data Really Mean for Your Business?
What Does Big Data Really Mean for Your Business?
 
The PHP Renaissance
The PHP RenaissanceThe PHP Renaissance
The PHP Renaissance
 
Lessons Learned with Distributed Systems at Bitly
Lessons Learned with Distributed Systems at BitlyLessons Learned with Distributed Systems at Bitly
Lessons Learned with Distributed Systems at Bitly
 
Considerations for Operating an OpenStack Cloud
Considerations for Operating an OpenStack CloudConsiderations for Operating an OpenStack Cloud
Considerations for Operating an OpenStack Cloud
 
All Things Open Opening Keynote
All Things Open Opening KeynoteAll Things Open Opening Keynote
All Things Open Opening Keynote
 
Building the iRODS Consortium
Building the iRODS ConsortiumBuilding the iRODS Consortium
Building the iRODS Consortium
 
The Gurubox Project: Open Source Troubleshooting Tools
The Gurubox Project: Open Source Troubleshooting ToolsThe Gurubox Project: Open Source Troubleshooting Tools
The Gurubox Project: Open Source Troubleshooting Tools
 
Open Source in Healthcare
Open Source in HealthcareOpen Source in Healthcare
Open Source in Healthcare
 
Open Source & The Internet of Things
Open Source & The Internet of ThingsOpen Source & The Internet of Things
Open Source & The Internet of Things
 
The Ember.js Framework - Everything You Need To Know
The Ember.js Framework - Everything You Need To KnowThe Ember.js Framework - Everything You Need To Know
The Ember.js Framework - Everything You Need To Know
 
Stop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case StudyStop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case Study
 
Trademarks and Your Free and Open Source Software Project
Trademarks and Your Free and Open Source Software ProjectTrademarks and Your Free and Open Source Software Project
Trademarks and Your Free and Open Source Software Project
 
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayI Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
 

Similar to Building Better Web APIs with Rails

Test-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) serviceTest-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) service
Jeroen Reijn
 
Palestra VCR
Palestra VCRPalestra VCR
Palestra VCR
Cássio Marques
 
Api development with rails
Api development with railsApi development with rails
Api development with rails
Edwin Cruz
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Rouven Weßling
 
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles ServiceAraport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
stevemock
 
API Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIsAPI Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIs
Tom Johnson
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
Rouven Weßling
 
Rack
RackRack
Rack
shen liu
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
Antonio Peric-Mazar
 
JSON REST API for WordPress
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPress
Taylor Lovett
 
Continuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWSContinuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWS
Danilo Poccia
 
KazooCon 2014 - Introduction to Kazoo APIs!
KazooCon 2014 - Introduction to Kazoo APIs!KazooCon 2014 - Introduction to Kazoo APIs!
KazooCon 2014 - Introduction to Kazoo APIs!
2600Hz
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API Documentation
Rouven Weßling
 
API testing - Japura.pptx
API testing - Japura.pptxAPI testing - Japura.pptx
API testing - Japura.pptx
TharindaLiyanage1
 
Streamlined Geek Talk
Streamlined Geek TalkStreamlined Geek Talk
Streamlined Geek Talk
Sarah Allen
 
Introduction à Ruby
Introduction à RubyIntroduction à Ruby
Introduction à Ruby
Microsoft
 
An introduction to the API for OnTime for IBM
An introduction to the API for OnTime for IBMAn introduction to the API for OnTime for IBM
An introduction to the API for OnTime for IBM
ontimesuite
 
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Tom Johnson
 
Women Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API WorkshopWomen Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API Workshop
Eddie Lau
 

Similar to Building Better Web APIs with Rails (20)

Test-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) serviceTest-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) service
 
Palestra VCR
Palestra VCRPalestra VCR
Palestra VCR
 
Api development with rails
Api development with railsApi development with rails
Api development with rails
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API Documentation
 
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles ServiceAraport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
 
API Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIsAPI Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIs
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
Rack
RackRack
Rack
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
 
JSON REST API for WordPress
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPress
 
Continuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWSContinuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWS
 
KazooCon 2014 - Introduction to Kazoo APIs!
KazooCon 2014 - Introduction to Kazoo APIs!KazooCon 2014 - Introduction to Kazoo APIs!
KazooCon 2014 - Introduction to Kazoo APIs!
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API Documentation
 
API testing - Japura.pptx
API testing - Japura.pptxAPI testing - Japura.pptx
API testing - Japura.pptx
 
Streamlined Geek Talk
Streamlined Geek TalkStreamlined Geek Talk
Streamlined Geek Talk
 
Introduction à Ruby
Introduction à RubyIntroduction à Ruby
Introduction à Ruby
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
An introduction to the API for OnTime for IBM
An introduction to the API for OnTime for IBMAn introduction to the API for OnTime for IBM
An introduction to the API for OnTime for IBM
 
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
 
Women Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API WorkshopWomen Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API Workshop
 

More from All Things Open

Building Reliability - The Realities of Observability
Building Reliability - The Realities of ObservabilityBuilding Reliability - The Realities of Observability
Building Reliability - The Realities of Observability
All Things Open
 
Modern Database Best Practices
Modern Database Best PracticesModern Database Best Practices
Modern Database Best Practices
All Things Open
 
Open Source and Public Policy
Open Source and Public PolicyOpen Source and Public Policy
Open Source and Public Policy
All Things Open
 
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
All Things Open
 
The State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil NashThe State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil Nash
All Things Open
 
Total ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScriptTotal ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScript
All Things Open
 
What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?
All Things Open
 
How to Write & Deploy a Smart Contract
How to Write & Deploy a Smart ContractHow to Write & Deploy a Smart Contract
How to Write & Deploy a Smart Contract
All Things Open
 
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
 Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
All Things Open
 
DEI Challenges and Success
DEI Challenges and SuccessDEI Challenges and Success
DEI Challenges and Success
All Things Open
 
Scaling Web Applications with Background
Scaling Web Applications with BackgroundScaling Web Applications with Background
Scaling Web Applications with Background
All Things Open
 
Supercharging tutorials with WebAssembly
Supercharging tutorials with WebAssemblySupercharging tutorials with WebAssembly
Supercharging tutorials with WebAssembly
All Things Open
 
Using SQL to Find Needles in Haystacks
Using SQL to Find Needles in HaystacksUsing SQL to Find Needles in Haystacks
Using SQL to Find Needles in Haystacks
All Things Open
 
Configuration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit InterceptConfiguration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit Intercept
All Things Open
 
Scaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship ProgramScaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship Program
All Things Open
 
Build Developer Experience Teams for Open Source
Build Developer Experience Teams for Open SourceBuild Developer Experience Teams for Open Source
Build Developer Experience Teams for Open Source
All Things Open
 
Deploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache BeamDeploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache Beam
All Things Open
 
Sudo – Giving access while staying in control
Sudo – Giving access while staying in controlSudo – Giving access while staying in control
Sudo – Giving access while staying in control
All Things Open
 
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML ApplicationsFortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
All Things Open
 
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
All Things Open
 

More from All Things Open (20)

Building Reliability - The Realities of Observability
Building Reliability - The Realities of ObservabilityBuilding Reliability - The Realities of Observability
Building Reliability - The Realities of Observability
 
Modern Database Best Practices
Modern Database Best PracticesModern Database Best Practices
Modern Database Best Practices
 
Open Source and Public Policy
Open Source and Public PolicyOpen Source and Public Policy
Open Source and Public Policy
 
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
 
The State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil NashThe State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil Nash
 
Total ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScriptTotal ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScript
 
What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?
 
How to Write & Deploy a Smart Contract
How to Write & Deploy a Smart ContractHow to Write & Deploy a Smart Contract
How to Write & Deploy a Smart Contract
 
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
 Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
 
DEI Challenges and Success
DEI Challenges and SuccessDEI Challenges and Success
DEI Challenges and Success
 
Scaling Web Applications with Background
Scaling Web Applications with BackgroundScaling Web Applications with Background
Scaling Web Applications with Background
 
Supercharging tutorials with WebAssembly
Supercharging tutorials with WebAssemblySupercharging tutorials with WebAssembly
Supercharging tutorials with WebAssembly
 
Using SQL to Find Needles in Haystacks
Using SQL to Find Needles in HaystacksUsing SQL to Find Needles in Haystacks
Using SQL to Find Needles in Haystacks
 
Configuration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit InterceptConfiguration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit Intercept
 
Scaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship ProgramScaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship Program
 
Build Developer Experience Teams for Open Source
Build Developer Experience Teams for Open SourceBuild Developer Experience Teams for Open Source
Build Developer Experience Teams for Open Source
 
Deploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache BeamDeploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache Beam
 
Sudo – Giving access while staying in control
Sudo – Giving access while staying in controlSudo – Giving access while staying in control
Sudo – Giving access while staying in control
 
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML ApplicationsFortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
 
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
 

Recently uploaded

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 

Recently uploaded (20)

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 

Building Better Web APIs with Rails

  • 1. BUILDINg BETTER WITH railS Devils Tower, WY web APIS @caikeCarlos Souza Code School
  • 5.
  • 7. “We need a snappier experience”
  • 8. “We’ve detected the majority of our visitors come from mobile devices. 
 
 We need to launch a native app
 as soon as possible!”
  • 9. “Does our web app expose an API ?”
  • 10. • Routes • CONNEG • AUTH • VERSION • Tests
  • 12. URLs are very important /gists /gists/public /gists/starred
  • 13.
  • 14. resources :projects GET
 POST
 PATCH (PUT) 
 DELETE ! ! ... Projects#index Projects#create Projects#show Projects#update Projects#destroy ... paths methods actions /projects /projects/:id
  • 16. resources :projects end end end member do post 'archive' 
 collection do get 'archived' do
  • 17. 
 ! get 'active' get 'suspended' ! ! ! post 'activate' post 'suspend' ! ! resources :projects end end end do member do post 'archive' 
 collection do get 'archived' post 'create_review'
  • 18. 
 ! get 'active' get 'suspended' ! ! ! post 'activate' post 'suspend' ! ! resources :projects end end end do member do post 'archive' 
 collection do get 'archived', to: 'archived_projects#index' , to: 'active_projects#index' , to: 'suspended_projects#index' , to: 'archived_projects#create' , to: 'active_projects#create' , to: 'suspended_projects#create' post 'create_review'
  • 19. 
 ! get 'active' get 'suspended' ! ! ! post 'activate' post 'suspend' ! ! resources :projects end end end do member do post 'archive' 
 collection do get 'archived' resources :reviews, only: :create , to: 'archived_projects#index' , to: 'active_projects#index' , to: 'suspended_projects#index' , to: 'archived_projects#create' , to: 'active_projects#create' , to: 'suspended_projects#create'
  • 20. app/controllers/api/projects_controller.rb module Api class ProjectsController < ApplicationController def index ... end end end
  • 21. ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'API' end config/initializers/inflections.rb module API class ProjectsController < ApplicationController def index ... end end end
  • 23. Client A API I’m a Rich Java$cript Application 
 and I want JSON! Hey, I’m an Enterprise Java Application and I want XML! (Ha Ha, Business!) ¯_(ツ)_/¯ Oi, soy un browser e quiero HTML! response in JSON respuesta en HTML response in XML Client B Client C content negotiation The process in which client and server determine the best representation for a response
 when many are available.
  • 24. /projects.json GET /projects
 Accept: application/json vs. Rails nicety Part of the HTTP spec client requests
  • 25. responders extracted out to 
 responders gem in Rails 4.2 module API class ProjectsController < ApplicationController respond_to :json, :xml ! def index @projects = Project.all ! respond_with(@projects) end end end
  • 26. calls #to_json calls #to_xml respond_to module API class ProjectsController < ApplicationController def index @projects = Project.recent ! respond_to do |format| format.json { render json: @projects, status: 200 } format.xml { render xml: @projects, status: 200 } end end end end
  • 27. JBuilder json.content format_content(@message.content) json.(@message, :created_at, :updated_at) ! json.author do json.name @message.creator.name.familiar json.url url_for(@message.creator, format: :json) end https://github.com/rails/jbuilder
  • 28. class ProjectSerializer < ActiveModel::Serializer attributes :id, :title, :amount ! embed :ids, include: true has_many :products end defaults to JSON-API https://github.com/rails-api/active_model_serializers ActiveModel::Serializers
  • 29. module SongsRepresenter include Roar::JSON::JsonApi name :songs ! property :id property :title end class SongRepresenter < Roar::Decorator include Roar::JSON::JsonApi name :songs ! property :id property :title end https://github.com/apotonick/roar using Mixins using Decorators Roar
  • 31. • Quick and Simple • Reutilizes existing credentials • HTTP spec (RFC 2617) http basic AUTH
  • 32. http basic AUTH module API class ProjectsController < ApplicationController before_action :authenticate_or_request ! protected ! def authenticate_or_request authenticate_or_request_with_http_basic do |user, pwd| User.authenticate(user, pwd) end end end end
  • 33. use the -u option $ curl -I http://carlos:secret@localhost:3000/projects ! HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 $ curl -Iu 'carlos:secret' http://localhost:3000/projects ! HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 http basic AUTH with curl
  • 34. • Can easily expire or regenerate tokens. • Any vulnerability is limited to API access. • Multiple tokens for each user. • Different access rules can be implemented. API Projects Forum Admin Client A token based auth
  • 35. token for the Backpack API providing the token Typically available out-of-band on a user settings page
  • 36. token for the Digital Ocean API For security purposes, 
 some services will only display the access token once. providing the token
  • 37. token based auth module API class ProjectsController < ApplicationController before_action :authenticate_or_request ! protected ! def authenticate_or_request authenticate_or_request_with_http_token do |token, opt| User.find_by(auth_token: token) end end end end
  • 38. UUID - Universally Unique Identifier GENERATING TOKENS RFC 4122
  • 39. We can use the Ruby standard library SecureRandom.uuid f4ea855f-d303-43e6-bee3-94581c0ecb21 90ab3255-ce33-4022-8349-b7979655b07c 371c760d-2539-41b9-b665-98c255d4c323 ... GENERATING TOKENS
  • 40. end def generate_auth_token .gsub(/-/,'') end omits the hyphensSecureRandom.uuid class User < ActiveRecord::Base before_create :set_auth_token ! private ! def set_auth_token return if auth_token.present?
 self.auth_token = generate_auth_token end ! a47a8e54b11c4de5a4a351734c80a14a 9fa8a147b10c4efca3e8592b3a1c2729 823c1c984d504f66a2e6cbb2eb69e842 ... GENERATING TOKENS
  • 41. $ curl -IH "Authorization: Token token=16d7d6089b8fe0c5e19bfe10bb156832" http://localhost:3000/episodes ! HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 use the -H option token based auth com curl
  • 43. MAJOR
 incompatible changes 
 MINOR
 backwards-compatible changes 
 PATCH
 backwards-compatible bug fixes http://semver.org/Semantic versioning Works great for software libraries
  • 44. V1/V1 feature X, feature Y /V2 feature X, feature Y, feature Z Compatible changes: • addition of a new format (i.e. JSON, XML ) • addition of a new property on a resource • renaming of an end-point (use 3xx status code!) • Only use major version. • Changes cannot break existing clients. • No need to bump version on compatible changes. versioning services
  • 46. https://www.mnot.net/blog/2012/12/04/api-evolution “The biggest way to avoid new 
 major versions is to make as many 
 of your changes backwards-compatible 
 as possible”
  • 48. API Unit Tests testing apis Not the time nor place to test business logic
  • 49. API • Status Code • Mime Types • Authentication WHAT SHOULD WE TEST ?
  • 50. API HOW SHOULD WE TEST ? Requesting endpoints and verifying responses $ rails g integration_test <doing-something>
  • 51. testing status code require 'test_helper' ! class ListingProjectsTest < ActionDispatch::IntegrationTest setup { host! 'api.example.com' } ! test 'returns list of projects' do get '/projects' assert_equal 200, response.status refute_empty response.body end end
  • 52. testing status code require 'test_helper' ! class ListingProjectsTest < ActionDispatch::IntegrationTest setup { host! 'api.example.com' } ! test 'returns list of projects' do get '/projects' assert_equal 200, response.status refute_empty response.body end end
  • 53. testing mime types class ListingProjectsTest < ActionDispatch::IntegrationTest setup { host! 'api.example.com' } 
 test 'returns projects in JSON' do get '/projects', {}, { 'Accept' => Mime::JSON } assert_equal Mime::JSON, response.content_type end test 'returns projects in XML' do get '/projects', {}, { 'Accept' => Mime::XML } assert_equal Mime::XML, response.content_type end end
  • 54. testing mime types class ListingProjectsTest < ActionDispatch::IntegrationTest setup { host! 'api.example.com' } 
 test 'returns projects in JSON' do get '/projects', {}, { 'Accept' => Mime::JSON } assert_equal Mime::JSON, response.content_type end test 'returns projects in XML' do get '/projects', {}, { 'Accept' => Mime::XML } assert_equal Mime::XML, response.content_type end end
  • 55. class ListingProjectsTest < ActionDispatch::IntegrationTest setup { @user = User.create! } setup { host! 'api.example.com' } ! test 'valid authentication with token' do get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}"} assert_equal 200, response.status assert_equal Mime::JSON, response.content_type end ! test 'invalid authentication' do get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}fake" } assert_equal 401, response.status end end testing access rules
  • 56. class ListingProjectsTest < ActionDispatch::IntegrationTest setup { @user = User.create! } setup { host! 'api.example.com' } ! test 'valid authentication with token' do get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}"} assert_equal 200, response.status assert_equal Mime::JSON, response.content_type end ! test 'invalid authentication' do get '/projects', {}, { 'Authorization' => "Token token=#{@user.auth_token}fake" } assert_equal 401, response.status end end testing access rules
  • 58. Thank you BUILDINg BETTER WITH railS@caikeCarlos Souza Code School web APIS Devils Tower, WY