REST API in Practice: What, why and how
1st step: forget about REST
1st step: forget about REST
1st step: forget about REST
2nd step: Let's build a software
2nd step: Let's build a software
Your Code
Your Code
Class Foo
Class Bar
Your Code
Class Foo
Foo.X()
Class Bar
Bar.A()
Your Code
Class Foo
Foo.X()
Foo._Y()
Class Bar
Bar.A()
Bar._B()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
Private methods used by Foo.X()
Private methods used by Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
You want to provide this service to your client
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
How?
You want to provide this service to your client
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
Just give the source code to your client
var Foo = require('./YourCode/Foo.js');
var Bar = require('./YourCode/Bar.js');
let f = new Foo();
let b = new Bar();
f.X();
b.A();
// So much win
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
What's the problem with this solution?
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
Your client doesn't know how to write code
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
Oh! There's another problem!
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
You don't want to expose private methods
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
What's your solution now?
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
What's your solution now?
"Expose a simple API" - you say
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
Easier access to functionality + access control
var YourCodeAPI = require('./YourCode/API.js');
let api = new YourCodeAPI();
api.Foo.X();
api.Bar.Y();
// So much win
Easier access to functionality + access control
var YourCodeAPI = require('./YourCode/API.js');
let api = new YourCodeAPI();
api.Foo.X();
api.Bar.Y();
// So much win
But Hey!
Easier access to functionality + access control
var YourCodeAPI = require('./YourCode/API.js');
let api = new YourCodeAPI();
api.Foo.X();
api.Bar.Y();
// So much win
Your client still doesn't know how to write code
But Hey!
How to solve this dilemma?
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
What's a server anyway?
What's a server anyway?
A simple loop always listening for requests
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
What's missing?
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
The main glue
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
Endpoints
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
Endpoints
/bar
/foo
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
Endpoints
/bar
/foo
that.get("/bar", Bar.A())
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
Endpoints
/bar
/foo
that.get("/bar", Bar.A())
that.get("/foo", Foo.X())
API
Foo.X()
Bar.A()
Your Code
Class Foo
Class Bar
Foo.X()
Foo._Y()
Foo._Z()
Bar.A()
Bar._B()
Bar._C()
JSON
JSON
HTTP Requests
Server
Req
Res
Endpoints
/bar
/foo
The flow of a request
Incoming request (JSON wrapped in HTTP)
The flow of a request
Incoming request (JSON wrapped in HTTP)
Server forwards to a endpoint
/foo
/bar
The flow of a request
Incoming request (JSON wrapped in HTTP)
Server forwards to a endpoint
/foo
/bar
The flow of a request
Incoming request (JSON wrapped in HTTP)
Server forwards to a endpoint
/foo
/bar
Server calls the method (Server.Foo.X())
The flow of a request
Incoming request (JSON wrapped in HTTP)
Server forwards to a endpoint
/foo
/bar
Server calls the method (Server.Foo.X())
Foo.X() processes the request and return response
Core logic
e.g: addDataset()
Core logic
e.g: addDataset()
Server method to handle Req/Res
e.g: Server.Dataset()
Core logic
e.g: addDataset()
Server method to handle Req/Res
Endpoint that will call a server method to handle the request
e.g: that.server.put("/dataset/:id", Server.dataset())
e.g: Server.Dataset()
Live coding!
REST API in Practice: What, why and how
By Rodrigo Araújo
REST API in Practice: What, why and how
- 2,050