KEMBAR78
RESTful Web API and MongoDB go for a pic nic | PDF
RESTful Web APIs
and MongoDB go for a picnic

Nicola Iarocci

@nicolaiarocci
Nicola Iarocci
Eve REST API Framework, Cerberus, Events
Co-founder @ gestionaleamica.com,
Book Author,
MongoDB Master
Nicola Iarocci
TL;DR
Passionate full stack developer
Il Piccolo
Libro di MongoDB
edizione italiana del libro di Karl Seguin
disponibile per il download @ nicolaiarocci.com
gestionaleamica.com
invoicing & accounting
gestionaleamica.com
your typical old school desktop application
gestionaleamica.com
now going web and mobile
gestionaleamica.com
“ we need a remote

API to keep everything in sync ”

-ha
A

ent
mo m
Before
Client

Database

Desktop!
Application

LAN/SQL
Initial draft
Clients

API

Database

RESTful !
Web API

“Cloud”

?

?

iOS
Android
Website
Desktop Client
Constraints
• minimum viable product first
• add features over time
• frequent database schema updates
• avoid downtime as much as possible
So we started
exploring new paths
MongoDB and REST
!

or why we picked MongoDB for our REST API
JSON-style data store
true selling point for me
JSON for transport
all client to API communication is going to be JSON
JSON & RESTful API
GET

Client

Mongo

JSON!

JSON!

accepted media type

(BSON)

maybe we can push directly to client?
JSON & RESTful API
GET

Client

API

JSON!

JSON!

accepted media type

subset of python dict!
(kinda)

almost.

Mongo
JSON!
(BSON)
JSON & RESTful API
POST

Client
JSON!
objects

API
JSON/dict!
maps to python dict!
(validation layer)

Mongo
JSON!
(BSON)

also works when posting (adding) items to the database
Similarity with
RDBMS
made NoSQL easy to grasp (even for a dumbhead like me)
Terminology
RDBMS

Mongo

Database

Database

Table

Collection

Rows(s)

JSON Document

Index

Index

Join

Embedding & Linking
What about Queries?
Queries in MongoDB are represented as JSON-style objects
// select * from things where x=3 and y="foo"
db.things.find({x: 3, y: "foo”});
Filtering and Sorting
let’s simply expose MongoDB syntax
?where={x: 3, y: "foo”}

Client
native!
Mongo!
query syntax

API
(very) thin
parsing!
& validation
layer

Mongo
JSON!
(BSON)
JSON
all along the pipeline
mapping to and from the database feels more natural
ORM
Where we’re going we don’t need ORMs.
Schema-less
dynamic documents allow for painless, progressive evolution
PyMongo
MongoDB drivers are beautiful. Really.
Also in MongoDB
• setup is a breeze
• lightweight
• fast inserts, updates and queries
• excellent documentation
• great support by 10gen
• great community
REST in practice
!

with some MongoDB love
Collections
API entry point + plural nouns
api.example.com/contacts

collection
to a Mongo
Maps
Document
API entry point + plural nouns + ID
api.example.com/contacts/4f46445fc88e201858000000

on ObjectID
o a collecti
Maps t
GET
Retrieving Resoruce Data
Resource GET
/contacts?where={“age”: {“$gt”: 20}}&projection={“lastname”: 1}

def get_collection(collection):!
documents = []!
cursor = db(collection).find(where, projection)!
for document in cursor:!
documents.append(document)!
return documents

find() accepts a python dict
as query expression, and
returns a cursor we can
iterate
Resource GET
/contacts?where={“age”: {“$gt”: 20}}&projection={“lastname”: 1}

def get_collection(collection):!
documents = []!
cursor = db(collection).find(where, projection)!
for document in cursor:!
documents.append(document)!
return documents

find() accepts a python dict
as query expression, and
returns a cursor we can
iterate
Resource GET
/contacts?where={“age”: {“$gt”: 20}}&projection={“lastname”: 1}

def get_collection(collection):!
documents = []!
cursor = db(collection).find(where, projection)!
for document in cursor:!
documents.append(document)!
return documents

find() accepts a python dict
as query expression, and
returns a cursor we can
iterate
JSON Rendering
JSON Rendering

from Mongo
straight
JSON Rendering
PATCH
Editing a Document
PATCHing
def patch_document(collection, original):!
(...)!
# Perform the update!
db(collection).update({"_Id": ObjectId(object_id)}, !
{"$set": updates})!

mongo update() method
commits updates to the
database.
PATCHing
def patch_document(collection, original):!
(...)!
# Perform the update!
db(collection).update({"_Id": ObjectId(object_id)}, !
{"$set": updates})!

udpate() takes the unique Id
of the document to update
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
POST
Creating Resources
POSTing
Take #1

def post(collection):!
(...)!
for key, item in docs.items():!
response[ID_FIELD] = db(collection).insert(item)

push document and get its
ObjectId back from Mongo.
like other CRUD operations,
inserting is trivial in
mongo.
POSTing
Take #2

Bulk inserts!!
(let’s look at the code)
after a lot of tinkering
we released an ambitious open

source project
Eve
REST API Framework powered by
Flask, MongoDB and good intentions

python-eve.org
Beta 0.2

• 1.000+ stargazers
• 120 forks

• 24 contributors
• 7.935 downloads
Eve Extensions
contributed by the community

• Eve-ElasticSearch
• Eve-SQLAlchemy
• Eve-Docs
• Eve-Mocks
Wanna see it running?
Hopefully it won’t explode right into my face
Initial draft
Clients

API

Database

RESTful !
Web API

“Cloud”

?

?

iOS
Android
Website
Desktop Client
Production
Clients

API

Database

Adam!

MongoDB

iOS
Android
Website
Desktop Client

eve instance
MongoDB Rocks!
your RESTful Web API
Thank you.
nicolaiarocci

RESTful Web API and MongoDB go for a pic nic