39
A-Z REST API S USING C AKE PHP ANTHON Y P UTIGNANO VP OF E NG INE ERING @ ABOUT.ME/ANT HONY.PUTI GNA NO

CakeFest 2013 - A-Z REST APIs

Embed Size (px)

Citation preview

Page 1: CakeFest 2013 - A-Z REST APIs

A-Z R

EST APIS

USING C

AKEPHP

ANTH

ON

Y PU

T IGN

ANO

VP OF E

NG

INEER IN

G @

ABOU

T.ME /A

NTH

ON

Y.PU

T IGN

ANO

Page 2: CakeFest 2013 - A-Z REST APIs

DATACOLLABORATI

ON

Page 3: CakeFest 2013 - A-Z REST APIs

NEW PLATFORM

• Backend REST API built using CakePHP

• Web client consumes the API via a thin Node.js server and a single-page AngularJS app

• Mobile client consumes the API with a PhoneGap-wrapped Sencha Touch app

Page 4: CakeFest 2013 - A-Z REST APIs

MISCONCEPTION:

"Building a REST API will be easy! All we need to do is hook up our controllers to a bunch of CRUD actions, serve them out like they exist in the database, and figure out a way to communicate in JSON/XML format!

Alright, is it happy hour yet!?”

Page 5: CakeFest 2013 - A-Z REST APIs

IN REALITY…

• Input/Output data purification

• Permissions

• Stateless authentication & authorization

• Cross-Origin Resource Sharing (CORS)

• Documentation

… and more lurking around the corner.

Page 6: CakeFest 2013 - A-Z REST APIs

API SCHEMA !== DATABASE SCHEMA• Many attribute names don’t match

column names

• Some attributes don’t map cleanly to columnar data

• Some resources don’t map cleanly to database tables

• API consumers expect a lot of related data to be accessible in a single request

Page 7: CakeFest 2013 - A-Z REST APIs

MODELS AREN’T JUST FOR TABLES• In a traditional app, a model generally

represents a table

• In an API, a model represents a resource

• New strategy• Share models when possible•Create new models for API-only resources• Set up attributes & relations for each API-accessible model

Page 8: CakeFest 2013 - A-Z REST APIs

CONFIGURE MODEL ATTRIBUTES

Page 9: CakeFest 2013 - A-Z REST APIs

SET UP API RELATIONS

Page 10: CakeFest 2013 - A-Z REST APIs

INPUT & OUTPUT PROCESSING• We now have at least 1 model for every API

resource

• We now have information about the attributes each API resource outputs

• We now have information about the relations each API resource relies on by default vs. by request

• We use this to input & output data automagically

How…?

Page 11: CakeFest 2013 - A-Z REST APIs

INPUT DATA COMPONENTWhat does it do?

Page 12: CakeFest 2013 - A-Z REST APIs

CONVERT TO COLUMNAR DATA• API request is submitted using API

resource & attribute names

• When processing this request, convert the request into column names that can be saved to tables

Page 13: CakeFest 2013 - A-Z REST APIs

CONVERT OPTIONS TO INTEGERS• Options are friendly on the API

consumer:`status` = “complete”

• Integers are friendly on the database:`status` = 1

• Don’t compromise one for the other – convert on input

Page 14: CakeFest 2013 - A-Z REST APIs

HONOR TYPECASTING• Use attribute configurations to

determine data type

• Convert ISO 8601 formatted dates

• Convert “false” string to`false` for booleans

• Convert “null” string to `NULL` for NULLables

• etc

Page 15: CakeFest 2013 - A-Z REST APIs

INTEGRATE FOREIGN KEYS• /forms parent resource

• /forms/{form.id}/records -> sub-resource

• When saving a record, automatically place `form_id` in POST data based on the value in the URL path

Page 16: CakeFest 2013 - A-Z REST APIs

BRING IN DENORMALIZED DATA• Form belongs to a Workspace

• Record belongs to a Form

• Record has a denormalized `workspace_id` column for easy reference & querying

• User shouldn’t have to submit the Workspace ID if they’ve already declared the Form ID

Page 17: CakeFest 2013 - A-Z REST APIs

QUERY COMPONENTWhat does it do?

Page 18: CakeFest 2013 - A-Z REST APIs

CONVERT TO COLUMNAR DATA• API request is submitted using API

resource & attribute names

• When processing this request, convert the conditions into column names that the app can use with a `find`

Page 19: CakeFest 2013 - A-Z REST APIs

CONVERT OPTIONS TO INTEGERS• Same `status` = “complete” -> `status`

= 1 conversion happens here

Page 20: CakeFest 2013 - A-Z REST APIs

INTEGRATE FOREIGN KEYS• Same integration of data happens here

• A query to /forms/{form.id}/records leads to an automatic inclusion of the Form ID in the query conditions

Page 21: CakeFest 2013 - A-Z REST APIs

PERMISSIONS• ACL is great for “static” permissions

• It’s not so great at handling “variable” permissions

… What’s the difference? How do we reconcile this?

Page 22: CakeFest 2013 - A-Z REST APIs

STATIC PERMISSIONS• App-wide “groups” of users (ie. default,

admin, root)

• Allow or block CRUD access to an entire resource

• Allow or block CRUD access to a resource’s attribute

Page 23: CakeFest 2013 - A-Z REST APIs

THE ACL IS OUR FRIEND$setActions is an anonymousfunction which sets up resourcerules that the `PermissionComponent`can understand.

$setCrud is an anonymousfunction which sets up attributerules.

Why anonymous functions?Hack to get past tough problems,but should be improved.

Page 24: CakeFest 2013 - A-Z REST APIs

DYNAMIC PERMISSIONS• Groups created by a resource (ie.

workspace member, workspace owner, etc)

• Allow or block CRUD access to a resource based on dynamic group member

Page 25: CakeFest 2013 - A-Z REST APIs

PERMISSIONS COMPONENT• canCreate() – returns boolean

• canUpdate() – returns boolean

• canDelete() – returns boolean

• requireConditions() – returns array of “safe” conditions based on requested query conditions + permitted access

Page 26: CakeFest 2013 - A-Z REST APIs

MODEL AS THE GO-TO SOURCE• isUserAuthorizedToCreate() – returns

boolean

• isUserAuthorizedToUpdate() – returns boolean

• isUserAuthorizedToDelete() – returns boolean

• userIsAuthorizedToReadSomeFieldName() – returns array of values that the user is allowed to query by, or “*” if all

Page 27: CakeFest 2013 - A-Z REST APIs

IS USER AUTHORIZED TO READ?

Page 28: CakeFest 2013 - A-Z REST APIs

AUTHENTICATION & AUTHORIZATION• Various different protocols

• Many costs & benefits to each

• We decided on oAuth 2 because it:• is simple• accommodates many different types of clients• is being adopted by some major providers

Page 29: CakeFest 2013 - A-Z REST APIs

OAUTH 2: THE SIMPLE VERSION:• Supports public (2-legged) & private (3-

legged) flows

• Uses an access token for 3-legged flows

Page 30: CakeFest 2013 - A-Z REST APIs

WHAT ARE THE CHALLENGES?• Clients need a way to get & refresh

access tokens

• App needs to authenticate the user with every request (it is stateless)

Page 31: CakeFest 2013 - A-Z REST APIs

OAUTH2 PLUGIN• There’s a lot to it, but basically…

• The `OAuth2Controller` handles all of the client’s token getting & refreshing needs via:• authorize()• grant()• token()

• The `OAuth2Authenticate` class is an authentication adapter which “logs the user in” on every request

Page 32: CakeFest 2013 - A-Z REST APIs

CONFIGURATION? EASY.

Page 33: CakeFest 2013 - A-Z REST APIs

CROSS-ORIGIN RESOURCE SHARING• API calls are often done from frontend

apps

• Browser will not less you make “cross-origin” (cross-domain) requests without extra request & response headers

• Cake doesn’t have any default options for this

Page 34: CakeFest 2013 - A-Z REST APIs

CORS PREFLIGHT DISPATCHER• Uses Cake 2.x dispatch filters

• If CORS request headers exist, it outputs CORS response headers

• Automatically stops propagation on OPTIONS requests

• Complete solution; all CORS logic in one place

Page 35: CakeFest 2013 - A-Z REST APIs

DOCUMENTATION• Should be as DRY as possible

• Should not sacrifice usability

• Interactive is better

• We chose Swagger UIhttps://github.com/wordnik/swagger-ui

Page 36: CakeFest 2013 - A-Z REST APIs

HOW TO KEEP IT DRY?• `ApiDocsShell` - uses combination of:

•Routes•Models•Attribute configurations• Permissions•Validation rulesto automagically build interactive documentation about resources.

Page 37: CakeFest 2013 - A-Z REST APIs

HOW TO KEEP IT USER FRIENDLY?• Sometimes a resource “dictionary” isn’t

enough

• Users need guidance

• Plain English descriptions help

• Pull those in based on convention•Attribute descriptions• Files which hold resource- & operation- level descriptions

Page 38: CakeFest 2013 - A-Z REST APIs

WHAT ARE WE MISSING?• JSON & XML formatting

• Error handling

• Routing

• Versioning

• Caching

• Links

• Rate limiting

• Monetization

• … it never really ends. Pick your battles wisely. Outsource functions if you can:http://www.3scale.net/

Page 39: CakeFest 2013 - A-Z REST APIs

OPEN SOURCED

github.com/Wizehive/cakephp-api-utils

Connect with me at:

about.me/anthony.putignano