$30 off During Our Annual Pro Sale. View Details »

RESTful Web API and MongoDB go for a pic nic

RESTful Web API and MongoDB go for a pic nic

Why and how MongoDB is a perfect match for building your next RESTful Web API.

Nicola Iarocci

October 26, 2013
Tweet

More Decks by Nicola Iarocci

Other Decks in Programming

Transcript

  1. RESTful Web APIs
    and MongoDB go for a picnic
    Nicola Iarocci @nicolaiarocci

    View Slide

  2. Nicola Iarocci
    Eve REST API Framework, Cerberus, Events
    Co-founder @ gestionaleamica.com,
    Book Author,
    MongoDB Master

    View Slide

  3. Nicola Iarocci
    TL;DR
    Passionate full stack developer

    View Slide

  4. Il Piccolo
    Libro di MongoDB
    edizione italiana del libro di Karl Seguin
    disponibile per il download @ nicolaiarocci.com

    View Slide

  5. gestionaleamica.com
    invoicing & accounting

    View Slide

  6. your typical old school desktop application
    gestionaleamica.com

    View Slide

  7. View Slide

  8. gestionaleamica.com
    now going web and mobile

    View Slide

  9. gestionaleamica.com
    “ we need a remote API to keep everything in sync ”
    A-ha moment

    View Slide

  10. Before
    Client
    LAN/SQL
    Database
    Desktop!
    Application

    View Slide

  11. Initial draft
    Clients
    “Cloud”
    Database
    RESTful !
    Web API
    API
    iOS
    Android
    Website
    Desktop Client
    ? ?

    View Slide

  12. Constraints
    • minimum viable product first
    • add features over time
    • frequent database schema updates
    • avoid downtime as much as possible

    View Slide

  13. So we started
    exploring new paths

    View Slide

  14. MongoDB and REST
    !
    or why we picked MongoDB for our REST API

    View Slide

  15. true selling point for me
    JSON-style data store

    View Slide

  16. all client to API communication is going to be JSON
    JSON for transport

    View Slide

  17. JSON & RESTful API
    JSON!
    accepted media type
    Client
    JSON!
    (BSON)
    Mongo
    GET
    maybe we can push directly to client?

    View Slide

  18. JSON & RESTful API
    JSON!
    accepted media type
    Client
    JSON!
    (BSON)
    Mongo
    JSON!
    subset of python dict!
    (kinda)
    API
    GET
    almost.

    View Slide

  19. 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

    View Slide

  20. made NoSQL easy to grasp (even for a dumbhead like me)
    Similarity with
    RDBMS

    View Slide

  21. Terminology
    RDBMS Mongo
    Database Database
    Table Collection
    Rows(s) JSON Document
    Index Index
    Join Embedding & Linking

    View Slide

  22. 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”});

    View Slide

  23. Filtering and Sorting
    native!
    Mongo!
    query syntax
    Client
    JSON!
    (BSON)
    Mongo
    (very) thin
    parsing!
    & validation
    layer
    API
    let’s simply expose MongoDB syntax
    ?where={x: 3, y: "foo”}

    View Slide

  24. mapping to and from the database feels more natural
    JSON
    all along the pipeline

    View Slide

  25. Where we’re going we don’t need ORMs.
    ORM

    View Slide

  26. dynamic documents allow for painless, progressive evolution
    Schema-less

    View Slide

  27. MongoDB drivers are beautiful. Really.
    PyMongo

    View Slide

  28. Also in MongoDB
    • setup is a breeze
    • lightweight
    • fast inserts, updates and queries
    • excellent documentation
    • great support by 10gen
    • great community

    View Slide

  29. REST in practice
    !
    with some MongoDB love

    View Slide

  30. Collections
    API entry point + plural nouns
    api.example.com/contacts
    Maps to a Mongo collection

    View Slide

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

    View Slide

  32. Retrieving Resoruce Data
    GET

    View Slide

  33. 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}

    View Slide

  34. 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}

    View Slide

  35. 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}

    View Slide

  36. JSON Rendering

    View Slide

  37. JSON Rendering
    straight from Mongo

    View Slide

  38. JSON Rendering

    View Slide

  39. Editing a Document
    PATCH

    View Slide

  40. 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})!

    View Slide

  41. 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})!

    View Slide

  42. 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

    View Slide

  43. Creating Resources
    POST

    View Slide

  44. 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.

    View Slide

  45. POSTing
    Take #2
    Bulk inserts!!
    (let’s look at the code)

    View Slide

  46. after a lot of tinkering
    we released an ambitious open source project

    View Slide

  47. Eve
    REST API Framework powered by
    Flask, MongoDB and good intentions
    python-eve.org

    View Slide

  48. Beta 0.2
    • 1.000+ stargazers
    • 120 forks
    • 24 contributors
    • 7.935 downloads

    View Slide

  49. Eve Extensions
    contributed by the community
    • Eve-ElasticSearch
    • Eve-SQLAlchemy
    • Eve-Docs
    • Eve-Mocks

    View Slide

  50. Wanna see it running?
    Hopefully it won’t explode right into my face

    View Slide

  51. Initial draft
    Clients
    “Cloud”
    Database
    RESTful !
    Web API
    API
    iOS
    Android
    Website
    Desktop Client
    ? ?

    View Slide

  52. Clients
    MongoDB
    Database
    Adam!
    eve instance
    API
    iOS
    Android
    Website
    Desktop Client
    Production

    View Slide

  53. MongoDB Rocks!
    your RESTful Web API

    View Slide

  54. Thank you.
    nicolaiarocci

    View Slide