rest in pieces

53

Upload: sparkfabrik

Post on 11-Apr-2017

58 views

Category:

Technology


3 download

TRANSCRIPT

REST in piecesSemiserious comparison of modern approaches

~$ whoami ↩Paolo “Stick” Pustorino#stickgrinder (almost everywhere)

CEO / COO @ SparkFabrik Srl

DRUMMER @ A couple of metal bands \m/_

WIZARD @ Cormyr’s Royal Court

FATHER @ Casamia

ANCHE @ Basta

~$ ls -alh ↩

What makes a great API

Which tools are available

Use-cases showdown

~$ iostat ↩

Completeness

Fairness

Experience

Substance

Openness

Lolcatz

******************************

A cut above the REST

What makes you API really stand out?

(from my perspective)

~$ curl -i -X GET https://stick.says/api-rules/1 ↩

URI should be nouns, not verbs

Verbs are already hard-coded in HTTP (GET, POST, …) so help yourself with

sensible semantics.

/cars/users/books/{id}

/getAllCars/userRemove/books/{id}/remove

~$ curl -i -X GET https://stick.says/api-rules/2 ↩

Never alter the state by GETs

We are not talking quantum physics, so you can observe things without changing their status!

HTTP supports state-alteration verbs. Use ‘em!

POST /carsDELETE /users/{uid}PUT /books/{id}

GET /addCarGET /userRemoveGET /books/{id}/update

~$ curl -i -X GET https://stick.says/api-rules/3 ↩

Don’t mix plurals and singulars

Don’t try to exaggerate semantics expressivity, keep things simple and use plurals.

GET /usersDELETE /users/{id}POST /users/{id}/reviews

GET /users (right but inconsistent with the following)

DELETE /user/{id}POST /user/{id}/review

~$ curl -i -X GET https://stick.says/api-rules/4 ↩

Use sub-resources as relational maps

Resource relations can be seen as ownership: hierarchical mapping helps here.

GET /users/{uid}/reviewsPUT /users/{uid}/reviews/{rid}

GET /reviews?byUser={uid}PUT /userReviews/{rid}

~$ curl -i -X GET https://stick.says/api-rules/5 ↩

Specify formats in HTTP headers

Exchange format information in HTTP headers and leave other means alone to avoid confusion

and messing with priorities.

Content-Type : application/jsonAccept : text/xml

PUT /reviews.jsonGET /reviews?format=xml

~$ curl -i -X GET https://stick.says/api-rules/6 ↩

Caching is built-in HTTP

You can save traffic and help frontend applications deliver light-speed experience with HTTP

caching strategies. Server-to-server connections can benefit too.

EtagVaryCache-ControlProxy-Revalidate

max-age (not a silver bullet)

no-cache (implement proper invalidation instead)

~$ curl -i -X GET https://stick.says/api-rules/7 ↩

Collections should be filterable, sortable and pageable

That’s what query parameters are there for! Be creative and use powerful expressions.

GET /users?sort=-age,+nameGET /users/{uid}/reviews?rate>=3&published=1GET /books?format=[epub,mobi]

GET /users?sortAsc=name&sortDesc=ageGET /userReviews?uid={uid}&rate>=3GET /books?format=epub&format=mobi

~$ curl -i -X GET https://stick.says/api-rules/8 ↩

Version your API

Or kittens will die en-masse on a per-request basis!

Really, you can break outdated consumers if you don’t.

GET /v1/users?sort=-age,+namePOST api.v2.stick.says/users

GET /users?format=oldPOST /users?format=2017

~$ curl -i -X GET https://stick.says/api-rules/9 ↩

Return meaningful status codes

HTTP status codes are to machines what error payloads are to humans. Use both and don’t return

meaningless 200 OK all around.

401 UNAUTHORIZED

{ "errors": [ { "user_msg": "You shall nooot paaass!!!", "internal_msg": "Balrogs are not welcome", "code": 666, “info": "http://stick.says/docs/v1/errors/666" } ]}

200 OK

{ “status” : “error”, "user_msg": "You shall nooot paaass!!!", "internal_msg": "Balrogs are not welcome", "code": 666, “info": "http://stick.says/docs/v1/errors/666"}

~$ curl -i -X GET https://stick.says/api-rules/10 ↩

Support modern authorization methods

Allow apps and services to act on behalf of users with clear scopes and tough security. Remember

authentication and authorization are not the same!

Oauth2JWT-TokensClient credentials

Basic-Auth (acceptable for S2S)

Session handling

RESTassured

Which options are available?

The Drupal way

~$ cat DRUPAL_WAY.txt | grep “pros” ↩

Drupal is finally PHP

REST is almost built-in (REST UI module helps if you like admin UIs)

Pervasive HATEOAS support via HAL

Leverages Symfony’s HTTP exceptions

Resource editing backend comes free

Views are natively RESTful

~$ cat DRUPAL_WAY.txt | grep “cons” ↩

Role-based permissions are not handled by middleware (@FIXME)

No PUTs, just PATCHes (really…)

Can’t do without HATEOAS / HAL (bloated output)

Its endpoint mapping is not ideal

RESTful Views are naive

Heavy bootstrap times

Still hard to integrate continuously

Full-stack frameworks

~$ cat FULLSTACK_FW.txt | grep “pros” ↩

Tailored persistence layer

Complex logic is often easy to implement

Small footprint

Easier multi-environment workflow (you only depend on code)

Continuous integration is a gas

Great cross-framework packages and extensions

~$ cat FULLSTACK_FW.txt | grep “cons” ↩

You may have to implement authentication by yourself

No built-in backoffice for resource management

You have to write all by yourself (even CRUD)

Boilerplate / redundant code across projects

Codebase policies / opinionation is often up to you

~$ cat FULLSTACK_FW.txt | grep “opts” ↩

Laravel / Lumen

Symfony 2/3 / Silex

Lithium (yes, still a good option if you don’t mind getting your hands dirty)

Slim and the like

Dedicated frameworks

~$ cat DEDICATED_FW.txt | grep “pros” ↩

All the pros of full-stack frameworks

Highly opinionated approach

Out-of-the-box support for most REST-related aspects (auth/auth, status-code

mapping, rate-limiting, versioning, format negotiation, etc)

Automatic API documentation generation

~$ cat DEDICATED_FW.txt | grep “cons” ↩

Smaller userbase / community

Few contribution, rely heavily on the shoulder of single maintainers

Risk to end up drowned in a fish bowl

* not that true for Dingo and not that issue for PHP Platform

~$ cat DEDICATED_FW.txt | grep “opts” ↩

API Platform

Dingo API (awesome package for Laravel and Lumen)

Epiphany

Recess PHP

API generation platforms

~$ cat API_PLATFORMS.txt | grep “pros” ↩

Make creating basic (and complex) APIs a breeze

Accessible to non-developers (or better said, frontend developers)

Make you focus on frontend application

Provide basic content management features

Generates API documentation

Pretty easy to scale with native cloud-oriented mindset

(often) Generates client SDKs (even for a number of platforms)

~$ cat API_PLATFORMS.txt | grep “cons” ↩

Logic is in configuration, not code (much like Drupal)

Smaller communities than Drupal

Higher vendor lock-in

Hard to use in team (not friendly to multi-environment workflows)

Suboptimal deployment to production

Rely on older PHP/FW versions

~$ cat API_PLATFORMS.txt | grep “opts” ↩

DreamFactory API Automation Platform (written in Laravel)

Zend Apigility

FRAPI

deployd (it’s node.js, not PHP, but it’s really good!)

put yourself toREST

What to chose for you next API?

~$ diff use_cases..drupal_8 ↩

Use Drupal 8 when...

You are exposing actual content via REST API

Your business logic is already on Drupal and REST becomes a necessary addition

Some specific feature of Drupal, unrelated to REST makes it the best candidate for

your project (and you can bear with the… rest, er…)

~$ diff use_cases..fullstack_fw ↩

Use a full-stack framework when...

You need fluid teamwork, multi-env workflow, fast testing, etc.

You want hassle-free Continuous Integration and Deploy

Your application has lot of custom functions aside “editorial” content management

You want to swim in the ocean, not a bathtub

You must provide enterprise-class support on the long term

~$ diff use_cases..dedicated_fw ↩

Use a dedicated framework when...

You want to speed up development, leveraging good boilerplate code

You want hassle-free Continuous Integration and Deploy

Your application is bound to remain a REST API

You don’t mind getting your hand dirty (smaller community)

You can afford supporting yourself on the long term (yes, even forking the framework)

~$ diff use_cases..api_platforms ↩

Use an API platform when...

You want to speed up development, leveraging easy low-coding tools

Your focus is on thick frontend application

You are akin to pay for managed cloud services

Heavy teamwork on the backend is not in sight

You don’t mind locking to vendors

give it aREST!

Enough blah blah blah...

Wanna chat?

THANKS