Skyrocketing Web APIs
-
Upload
daniel-cerecedo -
Category
Technology
-
view
418 -
download
0
Transcript of Skyrocketing Web APIs
Skyrocketing Web APIsBy making the right decisions
Daniel Cerecedo@dcerecedo
Why REST over HTTP?Why REST over HTTP?
@dcerecedoByteflair
Why REST over HTTP?Why REST over HTTP?
@dcerecedoByteflair
The limits of my language mean the limits of my world.
Everybody speaks HTTP
Developer UXDeveloper UX
@dcerecedoByteflair
HTTP is for browsers
Developer UXDeveloper UX
@dcerecedoByteflair
Developer in mind, not browsers
REST over HTTPREST over HTTP
@dcerecedoByteflair
ComponentsURIs
VerbsStatus Code
BodyHeaders
REST over HTTPREST over HTTP
@dcerecedoByteflair
Separate resource representation from contextual data
Representation Body→Contextual data Headers→
REST over HTTPREST over HTTP
@dcerecedoByteflair
HTTP status code to inform client about the result
2xx Ok→Other Ko→
4xx Client error→5xx Server error→
REST over HTTPREST over HTTP
@dcerecedoByteflair
Use best matching HTTP Status codes
Add specific application error codes to error responses
@dcerecedoByteflair
REST over HTTPREST over HTTP
Semantic of an API should be In the URI...but
Everybody thinks Verbs+URIs fit better on HTTP
@dcerecedoByteflair
REST over HTTPREST over HTTP
HypermediaHypermedia
@dcerecedoByteflair
HypermediaHypermedia
@dcerecedoByteflair
Applications can be modeled as state machines
@dcerecedoByteflair
HypermediaHypermedia
@dcerecedoByteflair
HypermediaHypermedia
@dcerecedoByteflair
HypermediaHypermedia
Model the problem domainIdentify domain resources
Identify resource state transitions
@dcerecedoByteflair
HypermediaHypermediaDomain resources
VehiclesUsers
SessionsResource state transitions
Create resourcesAssign owner to vehicle
Activate session with driver & vehicleDeactivate session
@dcerecedoByteflair
HypermediaHypermedia
Define resource representation formatsMime Types
Define roles for each Hypermedia ControlRel Types
@dcerecedoByteflair
HypermediaHypermediaGET /HeadersLink: <https://api.domain.com/vehicles>; rel=”vehicles”: <https://api.domain.com/users>; rel=”users”: <https://api.domain.com/sessions>; rel=”sessions”Body...
@dcerecedoByteflair
HypermediaHypermedia
GET /vehiclesHeadersLink: <https://api.domain.com/vehicles?page=1&size=20>; rel=”next”Body[ {... }, {…}, ...] Control links
@dcerecedoByteflair
HypermediaHypermedia
GET /sessions/1374Body{ ….
“vehicle”:”https://api.domain.com/vehicles/1”,“driver”:”https://api.domain.com/users/1”
}
These are also control links.
Use conventions to get full semantics!!
@dcerecedoByteflair
HypermediaHypermedia
GET /vehicles/1Body{ ….
“owner”:”https://api.domain.com/users/1”}
Relation types specify the role of the link
@dcerecedoByteflair
HypermediaHypermedia
GET /sessions/1374Body{ ….
“vehicle”:”https://api.domain.com/vehicles/1”,“driver”:”https://api.domain.com/persons/1”
}
@dcerecedoByteflair
HypermediaHypermedia
Let the client discover its resource access levelOptions
@dcerecedoByteflair
HypermediaHypermedia
ConventionsRel Types, Media Types, Methods, Status Codes
@dcerecedoByteflair
HypermediaHypermedia
Think as if you had to write a client and minimize the number of things you
have to know about the API beforehand
@dcerecedoByteflair
HypermediaHypermedia
A client and an API do not get decopupled
magically
Dynamic viewsDynamic views
@dcerecedoByteflair
Dynamic viewsDynamic views
@dcerecedoByteflair
We need different data access needs for the same resource depending on
the security context
Dynamic viewsDynamic views
@dcerecedoByteflair
Any User resource can be fully viewed by an administrator
A logged in user can fully view his User resourceOther users can only see his public data
Scenario
Dynamic viewsDynamic views
@dcerecedoByteflair
/users/{id}/owner/users/{id}/admin/users/{id}
One URI per role
Scenario
Dynamic viewsDynamic views
@dcerecedoByteflair
/users/{id}/owner/users/{id}/admin/users/{id}
One URI per role
Scenario
Dynamic viewsDynamic views
@dcerecedoByteflair
Partition the resourceGive different role access to each partition
Scenario
/users/{id}/users/{id}/my-private-data/users/{id}/data-about-me-only-the-admin-knows
Dynamic viewsDynamic views
@dcerecedoByteflair
One URI per resourceSelect one view at runtime depending on the security
context
Scenario
/users/{id}
Dynamic viewsDynamic views
@dcerecedoByteflair
1. Create a mechanism to define views2. Create a mechanism to define applicable views to a
resource3. Create a mechanism to define which view to apply
Dynamic viewsDynamic views
@dcerecedoByteflair
1
Dynamic viewsDynamic views
@dcerecedoByteflair
1
Dynamic viewsDynamic views
@dcerecedoByteflair
2
Dynamic viewsDynamic views
@dcerecedoByteflair
3
Updates & ConcurrencyUpdates & Concurrency
@dcerecedoByteflair
@dcerecedoByteflair
Two clients attempt to update the same resource concurrently
Representation is the state of the application
I want to avoid the second request to update a resource from an inconsistent representation
Updates & ConcurrencyUpdates & ConcurrencyScenario
@dcerecedoByteflair
Compare incoming resource and existing resource...
Updates & ConcurrencyUpdates & ConcurrencyScenario
@dcerecedoByteflair
Compare incoming resource and existing resource...If unequal reject...
Updates & ConcurrencyUpdates & ConcurrencyScenario
@dcerecedoByteflair
Compare incoming resource and existing resource...If unequal reject...
If possible inform the user which fields violated the precondition
Updates & ConcurrencyScenario
@dcerecedoByteflair
If we have dynamic views, then the same resource may have different fields for different security contexts
Updates & ConcurrencyUpdates & Concurrency
@dcerecedoByteflair
What if we don't want all fields to be updatable?
What if we need fine grained access control to fields?
Updates & ConcurrencyUpdates & ConcurrencyScenario
@dcerecedoByteflair
1. We need a mechanism to associate security expresions to fields
2. We need a mechanism to evaluate security expresions before changing the value of a field
Updates & ConcurrencyUpdates & Concurrency
@dcerecedoByteflair
Updates & ConcurrencyUpdates & Concurrency1
@dcerecedoByteflair
Updates & ConcurrencyUpdates & Concurrency2
Async RequestsAsync Requests
@dcerecedoByteflair
Async RequestsAsync Requests
@dcerecedoByteflair
How do we deal with transitions that are intrinsically asynchronous?
Async RequestsAsync Requests
@dcerecedoByteflair
How do we identify intrinsically async transitions?
There are state transitions beyond your control
It does not make sense to return a resource because we don't know the state of the resource after invoking the
transition
Async RequestsAsync Requests
@dcerecedoByteflair
Trucks are regularly reviewed and marked for repairing
Scenario
Ok
NeedsRepair
Repaired
Awaiting
Async RequestsAsync Requests
@dcerecedoByteflair
Trucks are regularly reviewed and marked for repairing
Scenario
Ok
NeedsRepair
Repaired
Within my organizations control
Awaiting
Async RequestsAsync Requests
@dcerecedoByteflair
Trucks are regularly reviewed and marked for repairing
Scenario
Ok
NeedsRepair
Repaired
Within my organizations control
Awaiting
PUT /trucks/6/repair202 Accepted
Async RequestsAsync Requests
@dcerecedoByteflair
Trucks are regularly reviewed and marked for repairing
Scenario
Ok
NeedsRepair
Repaired
Within my organizations control
Awaiting
PUT /trucks/6/repair202 Accepted
Async RequestsAsync Requests
@dcerecedoByteflair
How do we deal with task intensive state transitions?
Async RequestsAsync Requests
@dcerecedoByteflair
How do we deal with task intensive state transitions?
We make them async
@dcerecedoByteflair
Flexibility & DecouplingFlexibility & Decoupling
@dcerecedoByteflair
Flexibility & DecouplingFlexibility & Decoupling
Mediation Router + Message Broker
@dcerecedoByteflair
Flexibility & DecouplingFlexibility & Decoupling
Mail Template
FromToSubject
Template nameAmazon
Mailchimp
Elastic Mail
Scenario
@dcerecedoByteflair
Flexibility & DecouplingFlexibility & DecouplingScenario
@dcerecedoByteflair
Flexibility & DecouplingFlexibility & DecouplingScenario
@dcerecedoByteflair
Speaking in silveri18ni18n
@dcerecedoByteflair
Speaking in silveri18ni18n
GET /i18n/es_ESBody{
“country” : “ES”,“lang”: “es”,“data” : { “key”: “localized message”, ….}
}
Single Page App
@dcerecedoByteflair
API SpecificationAPI Specification
@dcerecedoByteflair
Byteflair
SwaggerSwaggerAPI API SpecificationSpecification
Swagger editor:http://editor.swagger.io/
En local:https://github.com/Byteflair/docker-swagger-editor
docker pull byteflair/swagger-editor docker run -d -p <port>:9000 byteflair/swagger-editor
Byteflair
RAMLRAMLAPI API SpecificationSpecification
API Designer:http://api-portal.anypoint.mulesoft.com/raml/api-designer
Imagen Docker: https://github.com/Byteflair/docker-raml-editor
docker pull byteflair/raml-editordocker run -d -p <port>:9013 byteflair/raml-editor
@dcerecedoByteflair
Oauth 2 CheatsheetOauth 2 Cheatsheet
@dcerecedoByteflair
Oauth 2 CheatsheetOauth 2 Cheatsheet
Client & User
User
Client
Trusted Untrusted
@dcerecedoByteflair
Oauth 2 CheatsheetOauth 2 Cheatsheet
Client & User
User
Client
Resource OwnerCredentials
Trusted UntrustedMy trusted native app
@dcerecedoByteflair
Oauth 2 CheatsheetOauth 2 Cheatsheet
Client & User
User
Client Client Credentials
Resource OwnerCredentials
Trusted Untrusted
A server app or CLI
@dcerecedoByteflair
Oauth 2 CheatsheetOauth 2 Cheatsheet
Client & User
User
Client
Authorization Code
Client Credentials
Resource OwnerCredentials
Trusted Untrusted
Third party apps
@dcerecedoByteflair
Oauth 2 CheatsheetOauth 2 Cheatsheet
Client & User
User
Client
Authorization CodeImplicit
Client Credentials
Resource OwnerCredentials
Trusted Untrusted
My single page app
@dcerecedoByteflair
Packaging & MonetizingPackaging & Monetizing
@dcerecedoByteflair
How to offer different products on top of the same API?
PackagingPackaging
@dcerecedoByteflair
How to offer different products on top of the same API?BUNDLING subsets of functionality
PackagingPackaging
@dcerecedoByteflair
How to offer different products on top of the same API?BUNDLING subsets of functionality
THROTTLING request
PackagingPackaging
@dcerecedoByteflair
How to offer different products on top of the same API?BUNDLING subsets of functionality
THROTTLING request
PackagingPackaging
Needs a proxy and means of updating policies
@dcerecedoByteflair
MonetizingMonetizing
@dcerecedoByteflair
ToolsTools
ToolsTools
@dcerecedoByteflair
@dcerecedoByteflair
“Weapons should be adapted to your personal qualities and be
one you can handle” Miyamoto Mushashi
@dcerecedoByteflair
Don't become an extremist
?Daniel Cerecedo
@dcerecedo
Thanks Gracias