RESTful Web APIs
and MongoDB go for a picnic
Nicola Iarocci @nicolaiarocci
Slide 2
Slide 2 text
Nicola Iarocci
Eve REST API Framework, Cerberus, Events
Co-founder @ gestionaleamica.com,
Book Author,
MongoDB Master
Slide 3
Slide 3 text
Nicola Iarocci
TL;DR
Passionate full stack developer
Slide 4
Slide 4 text
Il Piccolo
Libro di MongoDB
edizione italiana del libro di Karl Seguin
disponibile per il download @ nicolaiarocci.com
Slide 5
Slide 5 text
gestionaleamica.com
invoicing & accounting
Slide 6
Slide 6 text
your typical old school desktop application
gestionaleamica.com
Slide 7
Slide 7 text
No content
Slide 8
Slide 8 text
gestionaleamica.com
now going web and mobile
Slide 9
Slide 9 text
gestionaleamica.com
“ we need a remote API to keep everything in sync ”
A-ha moment
Slide 10
Slide 10 text
Before
Client
LAN/SQL
Database
Desktop!
Application
Slide 11
Slide 11 text
Initial draft
Clients
“Cloud”
Database
RESTful !
Web API
API
iOS
Android
Website
Desktop Client
? ?
Slide 12
Slide 12 text
Constraints
• minimum viable product first
• add features over time
• frequent database schema updates
• avoid downtime as much as possible
Slide 13
Slide 13 text
So we started
exploring new paths
Slide 14
Slide 14 text
MongoDB and REST
!
or why we picked MongoDB for our REST API
Slide 15
Slide 15 text
true selling point for me
JSON-style data store
Slide 16
Slide 16 text
all client to API communication is going to be JSON
JSON for transport
Slide 17
Slide 17 text
JSON & RESTful API
JSON!
accepted media type
Client
JSON!
(BSON)
Mongo
GET
maybe we can push directly to client?
Slide 18
Slide 18 text
JSON & RESTful API
JSON!
accepted media type
Client
JSON!
(BSON)
Mongo
JSON!
subset of python dict!
(kinda)
API
GET
almost.
Slide 19
Slide 19 text
JSON & RESTful API
JSON!
objects
Client
JSON!
(BSON)
Mongo
JSON/dict!
maps to python dict!
(validation layer)
API
POST
also works when posting (adding) items to the database
Slide 20
Slide 20 text
made NoSQL easy to grasp (even for a dumbhead like me)
Similarity with
RDBMS
Slide 21
Slide 21 text
Terminology
RDBMS Mongo
Database Database
Table Collection
Rows(s) JSON Document
Index Index
Join Embedding & Linking
Slide 22
Slide 22 text
Queries in MongoDB are represented as JSON-style objects
What about Queries?
// select * from things where x=3 and y="foo"
db.things.find({x: 3, y: "foo”});
mapping to and from the database feels more natural
JSON
all along the pipeline
Slide 25
Slide 25 text
Where we’re going we don’t need ORMs.
ORM
Slide 26
Slide 26 text
dynamic documents allow for painless, progressive evolution
Schema-less
Slide 27
Slide 27 text
MongoDB drivers are beautiful. Really.
PyMongo
Slide 28
Slide 28 text
Also in MongoDB
• setup is a breeze
• lightweight
• fast inserts, updates and queries
• excellent documentation
• great support by 10gen
• great community
Slide 29
Slide 29 text
REST in practice
!
with some MongoDB love
Slide 30
Slide 30 text
Collections
API entry point + plural nouns
api.example.com/contacts
Maps to a Mongo collection
Slide 31
Slide 31 text
Document
API entry point + plural nouns + ID
api.example.com/contacts/4f46445fc88e201858000000
Maps to a collection ObjectID
Slide 32
Slide 32 text
Retrieving Resoruce Data
GET
Slide 33
Slide 33 text
def get_collection(collection):!
documents = []!
cursor = db(collection).find(where, projection)!
for document in cursor:!
documents.append(document)!
return documents
Resource GET
find() accepts a python dict
as query expression, and
returns a cursor we can
iterate
/contacts?where={“age”: {“$gt”: 20}}&projection={“lastname”: 1}
Slide 34
Slide 34 text
def get_collection(collection):!
documents = []!
cursor = db(collection).find(where, projection)!
for document in cursor:!
documents.append(document)!
return documents
Resource GET
find() accepts a python dict
as query expression, and
returns a cursor we can
iterate
/contacts?where={“age”: {“$gt”: 20}}&projection={“lastname”: 1}
Slide 35
Slide 35 text
def get_collection(collection):!
documents = []!
cursor = db(collection).find(where, projection)!
for document in cursor:!
documents.append(document)!
return documents
Resource GET
find() accepts a python dict
as query expression, and
returns a cursor we can
iterate
/contacts?where={“age”: {“$gt”: 20}}&projection={“lastname”: 1}
Slide 36
Slide 36 text
JSON Rendering
Slide 37
Slide 37 text
JSON Rendering
straight from Mongo
Slide 38
Slide 38 text
JSON Rendering
Slide 39
Slide 39 text
Editing a Document
PATCH
Slide 40
Slide 40 text
PATCHing
mongo update() method
commits updates to the
database.
def patch_document(collection, original):!
(...)!
# Perform the update!
db(collection).update({"_Id": ObjectId(object_id)}, !
{"$set": updates})!
Slide 41
Slide 41 text
PATCHing
udpate() takes the unique Id
of the document to update
def patch_document(collection, original):!
(...)!
# Perform the update!
db(collection).update({"_Id": ObjectId(object_id)}, !
{"$set": updates})!
Slide 42
Slide 42 text
PATCHing
def patch_document(collection, original):!
(...)!
# Perform the update!
db(collection).update({"_Id": ObjectId(object_id)}, !
{"$set": updates})!
$set accepts a dict!
with the updates for the db
eg: {“active”: False}.
updates are atomic
Slide 43
Slide 43 text
Creating Resources
POST
Slide 44
Slide 44 text
def post(collection):!
(...)!
for key, item in docs.items():!
response[ID_FIELD] = db(collection).insert(item)
POSTing
Take #1
push document and get its
ObjectId back from Mongo.
like other CRUD operations,
inserting is trivial in
mongo.
Slide 45
Slide 45 text
POSTing
Take #2
Bulk inserts!!
(let’s look at the code)
Slide 46
Slide 46 text
after a lot of tinkering
we released an ambitious open source project
Slide 47
Slide 47 text
Eve
REST API Framework powered by
Flask, MongoDB and good intentions
python-eve.org