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