eve - rest api for humans™

103
REST API FOR HUMANS™ eve eve

Upload: nicola-iarocci

Post on 10-May-2015

3.795 views

Category:

Technology


2 download

DESCRIPTION

Introducing the Eve REST API Framework. FOSDEM 2014, Brussels PyCon Sweden 2014, Stockholm PyCon Italy 2014, Florence Python Meetup, Helsinki EuroPython 2014, Berlin

TRANSCRIPT

Page 1: Eve - REST API for Humans™

REST API FOR HUMANS™eveeve

Page 2: Eve - REST API for Humans™

nicolaiarocciCoFounder and Lead Dev @C2K

Open Source • MongoDB Master • Speaking • CoderDojo • PSF

Page 3: Eve - REST API for Humans™

PHILOSOPHY

Page 4: Eve - REST API for Humans™

YOU HAVE DATASTORED SOMEWHERE

Page 5: Eve - REST API for Humans™

YOU NEED A FULL FEATURED REST API

TO EXPOSE YOUR DATA

Page 6: Eve - REST API for Humans™

PIP INSTALL EVETO GET A FEATURE RICH RESTFUL WEB API FOR FREE

Page 7: Eve - REST API for Humans™

POWERED BY

Page 8: Eve - REST API for Humans™
Page 9: Eve - REST API for Humans™
Page 10: Eve - REST API for Humans™
Page 11: Eve - REST API for Humans™

QUICKSTART

Page 12: Eve - REST API for Humans™

#1 run.py

from eve import Eve app = Eve() !

if __name__ == '__main__': app.run()

Page 13: Eve - REST API for Humans™

#2 settings.py# just a couple API endpoints with no custom # schema or rules. Will just dump from people # and books db collections !

DOMAIN = { ‘people’: {} ‘books’: {} }

Page 14: Eve - REST API for Humans™

#3 launch the API

$ python run.py * Running on http://127.0.0.1:5000/

Page 15: Eve - REST API for Humans™

#4 enjoy$ curl -i http://127.0.0.1:5000/people { "_items": [], "_links": { "self": { "href": "127.0.0.1:5000/people", "title": "people" }, "parent": { "href": "127.0.0.1:5000", "title": "home"} } }

Page 16: Eve - REST API for Humans™

#4 enjoy$ curl -i http://127.0.0.1:5000/people { "_items": [], "_links": { "self": { "href": "127.0.0.1:5000/people", "title": “people" }, "parent": { "href": "127.0.0.1:5000", "title": “home"} } }

HATEOAS AT WORK HERE

Page 17: Eve - REST API for Humans™

#4 enjoy$ curl -i http://127.0.0.1:5000/people { "_items": [], "_links": { "self": { "href": "127.0.0.1:5000/people", "title": "people" }, "parent": { "href": "127.0.0.1:5000", "title": "home"} } }

CLIENTS CAN EXPLORE THE API PROGRAMMATICALLY

Page 18: Eve - REST API for Humans™

#4 enjoy$ curl -i http://127.0.0.1:5000/people { "_items": [], "_links": { "self": { "href": "127.0.0.1:5000/people", "title": "people" }, "parent": { "href": "127.0.0.1:5000", "title": "home"} } }

AND EVENTUALLY FILL THEIR UI

Page 19: Eve - REST API for Humans™

#4 enjoy$ curl -i http://127.0.0.1:5000/people { "_items": [], "_links": { "self": { "href": "127.0.0.1:5000/people", "title": "people" }, "parent": { "href": "127.0.0.1:5000", "title": "home"} } }

EMTPY RESOURCE AS WE DIDN’T CONNECT ANY DATASOURCE

Page 20: Eve - REST API for Humans™

settings.py

# let’s connect to a mongo instance !

MONGO_HOST = 'localhost' MONGO_PORT = 27017 MONGO_USERNAME = 'user' MONGO_PASSWORD = 'user' MONGO_DBNAME = ‘apitest'

Page 21: Eve - REST API for Humans™

settings.py# let’s also add some validation rules !

DOMAIN['people']['schema'] = { 'name': { 'type': 'string', 'maxlength': 50, 'unique': True} 'email': { 'type': 'string', 'regex': '^\S+@\S+$'}, 'location': { 'type': 'dict', 'schema': { 'address': {'type': 'string'}, 'city': {'type': 'string'}}}, 'born': {'type': ‘datetime'}}

Page 22: Eve - REST API for Humans™

settings.py# let’s also add some validation rules !

DOMAIN['people']['schema'] = { 'name': { 'type': 'string', 'maxlength': 50, 'unique': True} 'email': { 'type': 'string', 'regex': '^\S+@\S+$'}, 'location': { 'type': 'dict', 'schema': { 'address': {'type': 'string'}, 'city': {'type': 'string'}}}, 'born': {'type': ‘datetime'}}

THIS REGEX SUCKS. DON’T USE IN PRODUCTION

Page 23: Eve - REST API for Humans™

settings.py# allow write access to API endpoints # (default is [‘GET’] for both settings) !

# /people RESOURCE_METHODS = ['GET','POST'] !

# /people/<id> ITEM_METHODS = ['GET','PATCH','PUT','DELETE']

Page 24: Eve - REST API for Humans™

settings.py# allow write access to API endpoints # (default is [‘GET’] for both settings) !

# /people RESOURCE_METHODS = ['GET','POST'] !

# /people/<id> ITEM_METHODS = ['GET','PATCH','PUT','DELETE']

ADD/CREATE ONE OR MORE ITEMS

Page 25: Eve - REST API for Humans™

settings.py# allow write access to API endpoints # (default is [‘GET’] for both settings) !

# /people RESOURCE_METHODS = ['GET', 'POST'] !

# /people/<id> ITEM_METHODS = ['GET','PATCH','PUT','DELETE']

EDIT ITEM

Page 26: Eve - REST API for Humans™

settings.py# allow write access to API endpoints # (default is [‘GET’] for both settings) !

# /people RESOURCE_METHODS = ['GET', 'POST'] !

# /people/<id> ITEM_METHODS = ['GET','PATCH','PUT','DELETE']

REPLACE ITEM

Page 27: Eve - REST API for Humans™

settings.py# allow write access to API endpoints # (default is [‘GET’] for both settings) !

# /people RESOURCE_METHODS = ['GET', 'POST'] !

# /people/<id> ITEM_METHODS = ['GET','PATCH','PUT','DELETE']

YOU GUESSED IT

Page 28: Eve - REST API for Humans™

settings.py# a few more config options !

DOMAIN[‘people’].update( { ‘item_title’: ‘person’, ‘cache_control’: ‘max-age=10,must-revalidate, ‘cache_expires’: 10, ‘additional_lookup’: { ‘url’: ‘regex)”[\w]+”)’, ‘field’: ‘name’ } )

Page 29: Eve - REST API for Humans™

FEATURES

Page 30: Eve - REST API for Humans™

MONGO FILTERS?where={“lastname”: “Doe”}

Page 31: Eve - REST API for Humans™

PYTHON FILTERS?where=lastname==“Doe”

Page 32: Eve - REST API for Humans™

SORTING?sort=[(“total”: -1)]

SORT BY ‘TOTAL’, DESCENDING ORDER

Page 33: Eve - REST API for Humans™

PAGINATION?max_results=20&page=2

MAX 20 RESULTS/PAGE; PAGE 2

Page 34: Eve - REST API for Humans™

PROJECTIONS?projection={"avatar": 0}

RETURN ALL FIELDS BUT ‘AVATAR’

Page 35: Eve - REST API for Humans™

PROJECTIONS?projection={"lastname": 1}

ONLY RETURN ‘LASTNAME’

Page 36: Eve - REST API for Humans™

EMBEDDED RESOURCES?embedded={"author": 1}

Page 37: Eve - REST API for Humans™

NOT EMBEDDED

$ curl -i <url> !

HTTP/1.1 200 OK { "title": "Book Title", "description": "book description", "author": “52da465a5610320002660f94" }

RAW FOREIGN KEY (DEFAULT)

Page 38: Eve - REST API for Humans™

EMBEDDED

$ curl -i <url>?embedded={“author”: 1} !

HTTP/1.1 200 OK { "title": "Book Title", "description": "book description", "author": { “firstname”: “Mark”, “lastname”: “Green”, } }

REQUEST EMBEDDED AUTHOR

Page 39: Eve - REST API for Humans™

EMBEDDED

$ curl -i <url>?embedded={“author”: 1} !

HTTP/1.1 200 OK { "title": "Book Title", "description": "book description", "author": { “firstname”: “Mark”, “lastname”: “Green”, } }

EMBEDDED DOCUMENT

Page 40: Eve - REST API for Humans™

JSON AND XMLBUILT-IN FOR ALL RESPONSES

Page 41: Eve - REST API for Humans™

APPLICATION/JSON[ { "firstname": "Mark", "lastname": "Green", "born": "Sat, 23 Feb 1985 12:00:00 GMT", "role": ["copy", "author"], "location": {"city": "New York", "address": "4925 Lacross Road"}, "_id": "50bf198338345b1c604faf31", "_updated": "Wed, 05 Dec 2012 09:53:07 GMT", "_created": "Wed, 05 Dec 2012 09:53:07 GMT", "_etag": "ec5e8200b8fa0596afe9ca71a87f23e71ca30e2d", }, { "firstname": "John", ... }, ]

Page 42: Eve - REST API for Humans™

APPLICATION/JSON[ { "firstname": "Mark", "lastname": "Green", "born": "Sat, 23 Feb 1985 12:00:00 GMT", "role": ["copy", "author"], "location": {"city": "New York", "address": "4925 Lacross Road"}, "_id": "50bf198338345b1c604faf31", "_updated": "Wed, 05 Dec 2012 09:53:07 GMT", "_created": "Wed, 05 Dec 2012 09:53:07 GMT", "_etag": "ec5e8200b8fa0596afe9ca71a87f23e71ca30e2d", }, { "firstname": "John", ... }, ]

METAFIELDS ARE CONFIGURABLE

Page 43: Eve - REST API for Humans™

APPLICATION/XML<resource href=“localhost:5000/people" title="people"> <resource href="localhost:5000/people/<id>" title="person"> <lastname>Green</lastname> <firstname>Mark</firstname> <born>Wed, 05 Dec 2012 09:53:07 GMT</born> <role>author</role> <role>copy</role> <location> <address>4925 Lacross Road</address> <city>New York</city> </location> <_id>50bf198338345b1c604faf31</_id> <created>Wed, 05 Dec 2012 09:53:07 GMT</created> <updated>Sat, 18 Jan 2014 09:16:10 GMT</updated> <etag>ec5e8200b8fa0596afe9ca71a87f23e71ca30e2d</etag> </resource> ... <resource>

Page 44: Eve - REST API for Humans™

HATEOASHYPERMEDIA AS THE ENGINE OF APPLICATION STATE

Page 45: Eve - REST API for Humans™

HATEOAS{ “_links”: { “self”: { “href”: “/people”, “title”: “people” }, “parent”: { “href”: “/”, “title”: “home”}, “next”: { “href”: “/people?page=2”, “title”: “next page”}, “last”: { “href: “/people?page=10”, “title”: “last page”} } }

Page 46: Eve - REST API for Humans™

DOCUMENT VERSIONS?version=3

?version=all ?version=diffs

Page 47: Eve - REST API for Humans™

FILE STORAGEFILES ARE STORED IN GRIDFS BY DEFAULT

Page 48: Eve - REST API for Humans™

FILE STORAGE / SETTINGS

accounts = { 'name': {'type': 'string'}, 'pic': {'type': 'media'}, … }

Page 49: Eve - REST API for Humans™

FILE STORAGE

$ curl F “name=doe” —F “[email protected]" <url> HTTP/1.1 200 OK !

$ curl -i <url> HTTP/1.1 200 OK { "name": "john", "pic": "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAA…"}

MULTIPART/DATA-FORM POST

Page 50: Eve - REST API for Humans™

FILE STORAGE

$ curl F “name=doe” —F “[email protected]" <url> HTTP/1.1 200 OK !

$ curl -i <url> HTTP/1.1 200 OK { "name": "john", "pic": "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAA…"}

FILES RETURNED AS BASE64 STRINGS

Page 51: Eve - REST API for Humans™

FILE STORAGE (WITH META)

$ curl -i <url> HTTP/1.1 200 OK { "name": "john", "pic": { “file”: ”/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAA”, “content_type”: “image/jpeg”, “name”: “profile.jpg”, “length”: 8129 } }

EXTENDED_MEDIA_INFO: TRUE

Page 52: Eve - REST API for Humans™

RATE LIMITINGPOWERED

Page 53: Eve - REST API for Humans™

RATE LIMITING / SETTINGS

# Rate limit on GET requests: # 1 requests 1 minute window (per client) !

RATE_LIMIT_GET = (1, 60)

Page 54: Eve - REST API for Humans™

RATE LIMITING / GET #1

$ curl -i <url> !

HTTP/1.1 200 OK X-RateLimit-Limit: 1 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1390486659

Page 55: Eve - REST API for Humans™

RATE LIMITING / GET #2

$ curl -i <url> !

HTTP/1.1 429 TOO MANY REQUESTS

Page 56: Eve - REST API for Humans™

CONDITIONAL REQUESTSALLOW CLIENTS TO ONLY REQUEST

NON-CACHED CONTENT

Page 57: Eve - REST API for Humans™

IF-MODIFIED-SINCEIf-Modified-Since: Wed, 05 Dec 2012 09:53:07 GMT “Please return modified data since <date> or 304”

Page 58: Eve - REST API for Humans™

IF-NONE-MATCHIf-None-Match:1234567890123456789012345678901234567890

“Please return data if it has changed or 304”

>

Page 59: Eve - REST API for Humans™

BULK INSERTSINSERT MULTIPLE DOCUMENTS WITH A SINGLE REQUEST

Page 60: Eve - REST API for Humans™

BULK INSERTS / REQUEST$ curl -d ‘ [ { "firstname": "barack", "lastname": “obama" }, { "firstname": "mitt", "lastname": “romney” } ]' -H 'Content-Type: application/json’ <url>

Page 61: Eve - REST API for Humans™

BULK INSERTS / RESPONSE[ { "_status": "OK", "_updated": "Thu, 22 Nov 2012 15:22:27 GMT", "_id": "50ae43339fa12500024def5b", "_etag": "749093d334ebd05cf7f2b7dbfb7868605578db2c" "_links": {"self": {"href": “<url>”, "title": "person"}} }, { "_status": "OK", "_updated": "Thu, 22 Nov 2012 15:22:27 GMT", "_id": "50ae43339fa12500024def5c", "_etag": "62d356f623c7d9dc864ffa5facc47dced4ba6907" "_links": {"self": {"href": “<url>", "title": "person"}} } ]

COHERENCE MODE OFF: ONLY META FIELDS ARE RETURNED

Page 62: Eve - REST API for Humans™

BULK INSERTS / RESPONSE[ { "_status": "OK", "_updated": "Thu, 22 Nov 2012 15:22:27 GMT", "_id": "50ae43339fa12500024def5b", "_etag": "749093d334ebd05cf7f2b7dbfb7868605578db2c" "_links": {"self": {"href": “<url>”, "title": “person”}}, "firstname": "barack", "lastname": "obama", ! }, { "_status": "OK", "_updated": "Thu, 22 Nov 2012 15:22:27 GMT", "_id": "50ae43339fa12500024def5c", "_etag": "62d356f623c7d9dc864ffa5facc47dced4ba6907" "_links": {"self": {"href": “<url>", "title": "person"}} "firstname": "mitt", "lastname": "romney", } ]

COHERENCE MODE ON: ALL FIELDS RETURNED

Page 63: Eve - REST API for Humans™

DATA INTEGRITY CONCURRENCY CONTROL

NO OVERWRITING DOCUMENTS WITH OBSOLETE VERSIONS

Page 64: Eve - REST API for Humans™

DATA INTEGRITY / CONCURRENCY

$ curl -X PATCH -i <url> -d '{"firstname": "ronald"}'

HTTP/1.1 403 FORBIDDEN

IF-MATCH MISSING

Page 65: Eve - REST API for Humans™

DATA INTEGRITY / CONCURRENCY

$ curl -X PATCH -i <url> -H "If-Match: <obsolete_etag>” -d '{"firstname": “ronald”}' !

HTTP/1.1 412 PRECONDITION FAILED

ETAG MISMATCH

Page 66: Eve - REST API for Humans™

DATA INTEGRITY / CONCURRENCY

$ curl -X PATCH -i <url> -H “If-Match: 206fb4a39815cc0ebf48b2b52d7…” -d '{"firstname": “ronald"}' !

HTTP/1.1 200 OK

UPDATE ALLOWED IF CLIENT AND SERVER ETAG MATCH

Page 67: Eve - REST API for Humans™

DATA VALIDATION[ { "_status": "ERR", "_issues": {“name”: “value ‘clinton’ not unique”} }, { "_status": “OK", "_updated": "Thu, 22 Nov 2012 15:22:27 GMT”, "_id": “50ae43339fa12500024def5c", "_etag": “62d356f623c7d9dc864ffa5facc47dced4ba6907" "_links": { "self": { "href": “<url>”, "title": “person" } } } ]

Page 68: Eve - REST API for Humans™

AUTHENTICATION AND AUTHORIZATION

BASIC, TOKEN AND HMAC AUTH SUPPORTED

Page 69: Eve - REST API for Humans™

RUNS ON ALL PYTHONS2.6 / 2.7 / 3.3 / 3.4 and PyPy

Page 70: Eve - REST API for Humans™

AND MORECORS. CACHE CONTROL. VERSONING AND MORE.

Page 71: Eve - REST API for Humans™

BSD LICENSEDTEAR IT APART

Page 72: Eve - REST API for Humans™

DEVELOPERS

Page 73: Eve - REST API for Humans™

CUSTOM DATA LAYERSBUILD YOUR OWN DATA LAYER

Page 74: Eve - REST API for Humans™

SQL ALCHEMY (WIP)

Page 75: Eve - REST API for Humans™

SQLALCHEMY (WIP)

@registerSchema('invoices') class Invoices(CommonColumns): __tablename__ = 'invoices' number = db.Column(db.Integer) people = db.Column(db.Integer, db.ForeignKey('people._id'))

Page 76: Eve - REST API for Humans™

ELASTICSERCH

Page 77: Eve - REST API for Humans™

MONGODB (DEFAULT)

Page 78: Eve - REST API for Humans™

AUTHENTICATIONBASIC | TOKEN | HMAC

Page 79: Eve - REST API for Humans™

SECURITY AT A GLANCE

•global authentication

• custom endpoint auth

• public enpoints and methods

• role based access control

• user restricted resource access

Page 80: Eve - REST API for Humans™

three steps Auth

tutorial

Page 81: Eve - REST API for Humans™

#1

IMPORT BASE AUTH CLASS

Page 82: Eve - REST API for Humans™

#2

OVERRIDE CHECK_AUTH() METHOD

Page 83: Eve - REST API for Humans™

#3

PASS CUSTOM CLASS TO THE EVE APP

Page 84: Eve - REST API for Humans™

Done

Page 85: Eve - REST API for Humans™

CUSTOM VALIDATIONEXTEND THE BUILT-IN VALIDATION SYSTEM

Page 86: Eve - REST API for Humans™

CUSTOM VALIDATION

• add custom data types

• add custom validation logic

Page 87: Eve - REST API for Humans™

EVENT HOOKSPLUG CUSTOM ACTIONS INTO THE API LOOP

Page 88: Eve - REST API for Humans™

EVENT HOOKS AT A GLANCE•POST on_insert/on_inserted

•GET on_fetch/on_fetched

•PATCH on_update/on_updated

•PUT on_replace/on_replaced

•DELETE on_delete/on_deteled

• on_pre_<method>; on_post_<method>

Page 89: Eve - REST API for Humans™

TRANSFORM INCOMING DOCUMENTS

Page 90: Eve - REST API for Humans™

CUSTOM FILE STORAGEcustom MediaStorage subclasses to S3, File System, you name it

Page 91: Eve - REST API for Humans™

COMMUNITY

Page 92: Eve - REST API for Humans™

EVE-DOCSGENERATES DOCUMENTATION FOR EVE APIS IN HTML AND JSON FORMATS

CHARLES FLYNN

Page 93: Eve - REST API for Humans™

EVE-DOCS

Page 94: Eve - REST API for Humans™

EVE-MONGOENGINEENABLES MONGOENGINE ORM MODELS TO BE USED AS EVE SCHEMA

STANISLAV HELLER

Page 95: Eve - REST API for Humans™

EVE-ELASTICELASTICSEARCH DATA LAYER FOR EVE REST FRAMEWORK

PETR JASEK

Page 96: Eve - REST API for Humans™

EVE-MOCKERMOCKING TOOL FOR EVE POWERED REST APIS

THOMAS SILEO

Page 97: Eve - REST API for Humans™

{48: <you name here>}

Bryan Cattle Chr is toph Wi tzany Daniele Pizzolli dccrazyboy Dong Wei Ming Florian Rathgeber Francisco Corrales Morales Garrin Kimmell Gianfranco Palumbo Jaroslav Semančík Jean Boussier John Deng Jorge Puente Sarrín Josh Villbrandt Julien Barbot Ken Carpenter Kevin

Bowrin Kracekumar Nicolas Bazire Nicolas Carlier Ondrej

Slinták Petr Jašek Paul Doucet Robert Wlodarczyk Roberto Pasini Ronan Delacroix Roy Smith Ryan Shea Samuel Sutch Stanislav Heller Thomas Sileo Tomasz Jezierski Xavi Cubillas

Page 98: Eve - REST API for Humans™

NOW COOKING

Page 99: Eve - REST API for Humans™

GeoJSONSupport and validation for GeoJSON types

!

Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometricalCollection

Page 100: Eve - REST API for Humans™

JSONP*IN CASE YOUR BROWSER/JS FRAMEWORK CANT HANDLE C.O.R.S.

* PENDING SECURITY REVIEW

Page 101: Eve - REST API for Humans™

JSON-LD / HAL / SIREN*CURSTOM RENDER CLASSES

* MAYBE (UNDER CONSIDERATION)

Page 102: Eve - REST API for Humans™

python-eve.orgJOIN US

eve

Page 103: Eve - REST API for Humans™

nicolaiarocci

Thank you!