a bird's eye view on api development

Post on 06-Apr-2017

148 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Birds eye view on:API DEVELOPMENT

WHO ?

Frederick Vanbrabant Software engineermadewithlove

{ "id": 1, "title": "7 Things You Should NEVER Do to a potato", "subtitle": "you will never believe nr 4", "body": "Some body copy that will go on in great detail", "comments": [{ "id": 1, "body": "woah this changed my life" }, { "id": 2, "body": "I will never look at stuff in the same way" }]}

GET /getblogpost/1

Why is this not so great ?

Url is kinda structure less

What if we get loads of articles?

What if we get loads of comments?

Damn, we need to write documentation

Is this the best way to pinpoint a resource

GET /getblogposts/1

Let's look at that endpoint

HTTP verb

Endpoint

HTTP verbs

HTTP verbs

HTTP != CRUD

HTTP verbs

Verb Return HTTP Code

POST 201

Sends a payload to the server,Returns an empty body.

HTTP verbs

Verb Return HTTP Code

POST 201

POST /posts

{ "title": "Why cheese is better then real friends", "body": "People only stand in the way of you and your cheese!"}

Post body

HTTP verbs

Verb Return HTTP Code

GET 200

Does not send a payloadReturns a collection of or a single resource

HTTP verbs

Verb Return HTTP Code

GET 200

GET /posts/2

{ "title": "How to fake your own death", "body": "You can buy cheese with the insurance money!"}

Return body

HTTP verbs

Verb Return HTTP Code

PUT 204

Updates a resource (needs the entire object)Returns an empty body.

HTTP verbs

Verb Return HTTP Code

PUT 204

PUT /posts/2

{ "title": "Help I'm stuck in a keynote making factory", "body": "Send cheese!"}

Put body

HTTP verbs

Verb Return HTTP Code

PATCH 200

Accepts instructions to update the resourceReturns the resource

Wait what?

Accepts instructions to update the resourcereturns the resource

PATCH /artists/kanye/[ { "op": "replace", "path": "artists/kanye/cars", "value": 7 },]

Wait what?

Accepts instructions to update the resourcereturns the resource

PATCH /artists/kanye[ {"cars" : 7}]

Content-Type: application/partial-update-json

HTTP verbs

Verb Return HTTP Code

DELETE 204

Removed the resourceReturns an empty body.

HTTP verbs

Verb Return HTTP Code

DELETE 204

DELETE /posts/1

HTTP CODE

HTTP CODE

Range 1XX - Information

Code What it means

100 continue

101 Switching Protocols

102 Processing

HTTP CODE

Range 2XX - Success

Code What it means

200 Ok

201 Created

202 Accepted

HTTP CODE

Range 3XX - Redirection

Code What it means

301 Moved

300 Multiple Choices

HTTP CODE

Range 4XX - Client error

Code What it means

400 Bad Request

401 Unauthorized

404 Not found

HTTP CODE

Range 5XX - Server error

Code What it means

500 Internal Server Error

503 Service Unavailable

504 Gateway Timeout

HTTP HEADERS

HTTP HEADERS

Send on each request and response

Meta data to the call

Can define custom headers

HTTP HEADERS

GET / HTTP/1.1

Host: www.google.comConnection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/X-Chrome-UMA-Enabled: 1X-Client-Data: CIS2yQEIpbbJAQjEtskBCOCUygEI+pjKAQjznMoBAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdchAccept-Language: nl,en;q=0.8Cookie: *Cookie data*

Request

HTTP HEADERS

Status: 200 (OK)

Date: Fri, 08 Jul 2016 13:59:05 GMTExpires: -1Cache-Control: private, max-age=0Content-Type: text/html; charset=ISO-8859-1X-Xss-Protection: 1; mode=blockX-Frame-Options: SAMEORIGINSet-Cookie: NID=81=x8aqWN0zsVHK2QcLEZca6603H8BYJxXP6bfjQl0cT82iM4j7fE3V9wH2qbpXW0DAAPL3G56n9ID-H_RCP-w9eVxA-mu9XV-oX-oE00qrVwRgzXV334c7XpsX2DDuTdcq; expires=Sat, 07-Jan-2017 13:59:05 GMT; path=/; domain=.google.be; HttpOnlyAccept-Ranges: noneVary: Accept-EncodingTransfer-Encoding: chunked

*HTML, JSON, XML OR WHATEVER*

Response

What about the endpoint

GET /getblogposts/1

What about the endpoint

GET /posts/1

What about the endpoint

GET /posts/1

Nouns are good, verbs are bad

Use plurals

What about the endpoint

GET /posts/1

GET /posts/1/comments

GET /posts/1/comments/15

OR

GET /comments/15

What about the endpoint

GET /posts

GET /posts/slugs-are-allowed

What about the endpoint

GET users/4b3403665fea6/posts/4b340550242239

What about the endpoint

Endpoint structure != database structure

We still 200 ?

Let's check out that body?

{ "id": 1, "title": "7 Things You Should NEVER Do to a potato", "subtitle": "you will never believe nr 4", "body": "Some body copy that will go on in great detail", "comments": [{ "id": 1, "body": "woah this changed my life" }, { "id": 2, "body": "I will never look at stuff in the same way" }]}

Let's use a standard

Battle tested and growing up to be the standard

{ "count": 87, "next": "http://swapi.co/api/people/?page=2", "previous": null, "results": [ { "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "http://swapi.co/api/planets/1/", "films": [ "http://swapi.co/api/films/6/", "http://swapi.co/api/films/3/", "http://swapi.co/api/films/2/", "http://swapi.co/api/films/1/", "http://swapi.co/api/films/7/" ], "species": [ "http://swapi.co/api/species/1/" ], "vehicles": [ "http://swapi.co/api/vehicles/14/", "http://swapi.co/api/vehicles/30/" ], "starships": [ "http://swapi.co/api/starships/12/", "http://swapi.co/api/starships/22/" ], "created": "2014-12-09T13:50:51.644000Z", "edited": "2014-12-20T21:17:56.891000Z", "url": "http://swapi.co/api/people/1/"

{ "count": 87, "next": "http://swapi.co/api/people/?page=3", "previous": "http://swapi.co/api/people/?page=1", "results": [ .... ]}

Links ?

page-based

{ "count": 30, "next": "http://swapi.co/api/people/?offset=60&limit=30", "previous": "http://swapi.co/api/people/?offset=0&limit=30", "results": [ .... ]}

Links ?

offset-based

{ "count": 87, "next": "http://swapi.co/api/people/?cursor=1374004777531007833", "previous": "http://swapi.co/api/people/?cursor=2627305797328905258", "results": [ .... ]}

Links ?

cursor-based

{ "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "http://swapi.co/api/planets/1/", "films": [ "http://swapi.co/api/films/6/", "http://swapi.co/api/films/3/", "http://swapi.co/api/films/2/", "http://swapi.co/api/films/1/", "http://swapi.co/api/films/7/" ], "species": [ "http://swapi.co/api/species/1/" ], "vehicles": [ "http://swapi.co/api/vehicles/14/", "http://swapi.co/api/vehicles/30/" ], "starships": [ "http://swapi.co/api/starships/12/", "http://swapi.co/api/starships/22/" ], "created": "2014-12-09T13:50:51.644000Z", "edited": "2014-12-20T21:17:56.891000Z", "url": "http://swapi.co/api/people/1/"}

Wait I can't have nested-resources?

Wait I can't have nested-resources?

This is not really HTTP now is it ?

Think about howyou surf the webThat's pretty nice right ?

HATEOASHypermedia as the Engine of Application State

HATEOAS Hypermedia as the Engine ofApplication State

{ "name": "Boba Fett", "height": "183", "mass": "78.2", "hair_color": "black", "skin_color": "fair", "eye_color": "brown", "birth_year": "31.5BBY", "gender": "male", "homeworld": "http://swapi.co/api/planets/10/", "films": [ "http://swapi.co/api/films/5/", "http://swapi.co/api/films/3/", "http://swapi.co/api/films/2/" ], "species": [ "http://swapi.co/api/species/1/" ], "vehicles": [], "starships": [ "http://swapi.co/api/starships/21/" ], "created": "2014-12-15T12:49:32.457000Z", "edited": "2014-12-20T21:17:50.349000Z", "url": "http://swapi.co/api/people/22/"

HATEOAS

"I'm not going to make 500 calls just to get somecomments"

HATEOAS

"I'm not going to make 500 calls just to get somecomments"

GET /films

GET /films/4,5,6

HATEOAS

"Can't you just add the resources to the url?"

GET /articles/1?include=comments,likes

QUERY PARAMETERS

Filter the response to what's valid on the query

GET /cheeses?type=brie,cheddar

GET /cheeses?type[]=brie&type[]=cheddar

AUTH

AUTH

AUTH

- HTTP Basic- JWT- OAuth 2.0

HTTP Basic

- Super easy- Not super safe

JWT (Json web tokens)

- No database hassle- Needs some knowledge

JWT (Json web tokens)

ServerClient

make new callswith the token

Return token

Send credentials

JWT (Json web tokens)

https://jwt.io/

OAuth2

- Very secure and very flexible- Can be daunting to setup

OAuth2

ServerClient

make new callswith the token

Return token +Refresh token

Send credentials

OAuth2

ServerClient

make new callswith the token

Return token +Refresh token

Send refresh token

API VERSIONING

API VERSIONING

YOU SHOULD NOTHAVE TO VERSION AN

API!

API VERSIONING

BUT YOU WILL HAVETO EVENTUALLY

API VERSIONING

GET /api/v1/artists/taylor-swift

API VERSIONING

GET /api/v1/artists/taylor-swift

The good The bad

Easy to implement Routes should not change

Easy to see what versionwe are on

Meta data should be in aheader

API VERSIONING

GET /api/artists/taylor-swiftx-api-version: 1

API VERSIONING

The good The bad

Meta data is in the header Custom header ... ?

Url does not change You need documentation

Url does not change

GET /api/artists/taylor-swiftx-api-version: 1

API VERSIONING

GET /api/artists/taylor-swiftAccept: application/vnd.website.v1+json

API VERSIONING

The good The bad

Meta data is in the header Harder to test

Standard http header You need documentation

GET /api/artists/taylor-swiftAccept: application/vnd.website.v1+json

Random TIPS

START WITH DOCUMENTATION

Random TIPS

LOOK AT THE USER FIRST, NOT THE TECH(A GOOD API DOES NOT NEED TO BE REST)

Random TIPS

TYPE CAST YOUR RETURN VALUES

Random TIPS

CONSISTENCY IS KING

Random TIPS

TEST YOUR ENDPOINTS

Random TIPS

NEVER TRUST YOUR USERS

Random TIPS

Use PHP?

Laravel: https://github.com/dingo/apiVanilla: https://thephpleague.com https://github.com/spatie

Use Python?

Django: http://www.django-rest-framework.org

Random TIPS

Want to know more?

This talks in text form:https://blog.madewithlove.be/post/birdseye-view-on-api

Phil Sturgeon's book:

https://leanpub.com/build-apis-you-wont-hate

Great O'Reily book RESTful Web APIs:

http://shop.oreilly.com/product/0636920028468.do

Questions!

Twitter: TheEdonian

THANKS !

top related