[drupalday2017] - rest in pieces

53

Upload: drupalday

Post on 21-Mar-2017

43 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: [drupalday2017] - REST in pieces
Page 2: [drupalday2017] - REST in pieces

REST in piecesSemiserious comparison of modern approaches

Page 3: [drupalday2017] - REST in pieces

~$ 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

Page 4: [drupalday2017] - REST in pieces

~$ ls -alh ↩

What makes a great API

Which tools are available

Use-cases showdown

Page 5: [drupalday2017] - REST in pieces

~$ iostat ↩

Completeness

Fairness

Experience

Substance

Openness

Lolcatz

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

Page 6: [drupalday2017] - REST in pieces
Page 7: [drupalday2017] - REST in pieces
Page 8: [drupalday2017] - REST in pieces

A cut above the REST

What makes you API really stand out?

(from my perspective)

Page 9: [drupalday2017] - REST in pieces

~$ 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.

Page 10: [drupalday2017] - REST in pieces

/cars/users/books/{id}

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

Page 11: [drupalday2017] - REST in pieces

~$ 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!

Page 12: [drupalday2017] - REST in pieces

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

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

Page 13: [drupalday2017] - REST in pieces

~$ 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.

Page 14: [drupalday2017] - REST in pieces

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

GET /users (right but inconsistent with the following)

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

Page 15: [drupalday2017] - REST in pieces

~$ 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.

Page 16: [drupalday2017] - REST in pieces

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

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

Page 17: [drupalday2017] - REST in pieces

~$ 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.

Page 18: [drupalday2017] - REST in pieces

Content-Type : application/jsonAccept : text/xml

PUT /reviews.jsonGET /reviews?format=xml

Page 19: [drupalday2017] - REST in pieces

~$ 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.

Page 20: [drupalday2017] - REST in pieces

EtagVaryCache-ControlProxy-Revalidate

max-age (not a silver bullet)

no-cache (implement proper invalidation instead)

Page 21: [drupalday2017] - REST in pieces

~$ 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.

Page 22: [drupalday2017] - REST in pieces

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

Page 23: [drupalday2017] - REST in pieces

~$ 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.

Page 24: [drupalday2017] - REST in pieces

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

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

Page 25: [drupalday2017] - REST in pieces

~$ 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.

Page 26: [drupalday2017] - REST in pieces

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"}

Page 27: [drupalday2017] - REST in pieces

~$ 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!

Page 28: [drupalday2017] - REST in pieces

Oauth2JWT-TokensClient credentials

Basic-Auth (acceptable for S2S)

Session handling

Page 29: [drupalday2017] - REST in pieces

RESTassured

Which options are available?

Page 30: [drupalday2017] - REST in pieces

The Drupal way

Page 31: [drupalday2017] - REST in pieces

~$ 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

Page 32: [drupalday2017] - REST in pieces

~$ 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

Page 33: [drupalday2017] - REST in pieces

Full-stack frameworks

Page 34: [drupalday2017] - REST in pieces

~$ 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

Page 35: [drupalday2017] - REST in pieces

~$ 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

Page 36: [drupalday2017] - REST in pieces

~$ 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

Page 37: [drupalday2017] - REST in pieces

Dedicated frameworks

Page 38: [drupalday2017] - REST in pieces

~$ 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

Page 39: [drupalday2017] - REST in pieces

~$ 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

Page 40: [drupalday2017] - REST in pieces

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

API Platform

Dingo API (awesome package for Laravel and Lumen)

Epiphany

Recess PHP

Page 41: [drupalday2017] - REST in pieces

API generation platforms

Page 42: [drupalday2017] - REST in pieces

~$ 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)

Page 43: [drupalday2017] - REST in pieces

~$ 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

Page 44: [drupalday2017] - REST in pieces

~$ 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!)

Page 45: [drupalday2017] - REST in pieces

put yourself toREST

What to chose for you next API?

Page 46: [drupalday2017] - REST in pieces

~$ 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…)

Page 47: [drupalday2017] - REST in pieces

~$ 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

Page 48: [drupalday2017] - REST in pieces

~$ 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)

Page 49: [drupalday2017] - REST in pieces

~$ 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

Page 50: [drupalday2017] - REST in pieces

give it aREST!

Enough blah blah blah...

Page 51: [drupalday2017] - REST in pieces

Wanna chat?

Page 52: [drupalday2017] - REST in pieces

THANKS

Page 53: [drupalday2017] - REST in pieces