Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MongoDB and REST APIs A Match Made in Heaven

MongoDB and REST APIs A Match Made in Heaven

Exposing MongoDB over the internet through a RESTful API is becoming a common pattern, and for very good reasons. Your REST API provides a nice layer of abstraction, isolation and validation above the actual datastore while providing access to all kind of clients. At the same time MongoDB, with its BSON store, is ideal for serving data over the Internet. But designing first, and then building a robust and scalable REST API is not an easy task.

EVE is an open source framework allowing anyone to effortlessly expose MongoDB data sources over highly customizable, fully featured RESTful Web Services. Initially developed to solve our own internal use case, EVE has been getting a lot of traction since its open source release in 2012.

In this talk I will go through the reasons that make MongoDB a good match for most RESTful APIs. I will then show some prominent EVE features and illustrate how one can quickly and easily go online with a RESTful MongoDB front-end. I also plan to illustrate some common pitfalls on MongoDB+EVE/REST deployments.

Nicola Iarocci

October 16, 2015
Tweet

More Decks by Nicola Iarocci

Other Decks in Technology

Transcript

  1. Good Morning
    Percona Live Amsterdam 2015

    View Slide

  2. Who Am I
    fighting back against impostor syndrome

    View Slide

  3. Nicola Iarocci
    Co-founder and CTO at CIR 2000

    View Slide

  4. Nicola Iarocci
    MongoDB Master

    View Slide

  5. Nicola Iarocci
    Open Source junkie
    Eve •
    Cerberus •
    Events •
    Flask-Sentinel •
    Eve.NET •
    Etc.

    View Slide

  6. Nicola Iarocci
    Consultant
    Mongo • RESTful Services • Python • My Open Source Projects

    View Slide

  7. Nicola Iarocci
    CoderDojo
    Coding Clubs for Kids

    View Slide

  8. MongoDB & REST APIs
    A Match Made in Heaven

    View Slide

  9. Agenda

    View Slide

  10. Agenda
    1. Our use case for a RESTful API

    View Slide

  11. Agenda
    2. What is a RESTful API and why we need it

    View Slide

  12. Agenda
    3. Why MongoDB is a good match for RESTful Services

    View Slide

  13. Agenda
    4. Build and run a MongoDB RESTful Service from scratch, live on stage.

    View Slide

  14. Agenda
    5. Stories from the field (if there’s any time left, which I doubt)

    View Slide

  15. The Case
    for RESTful Web APIs

    View Slide

  16. Amica 10
    invoicing & accounting for italian small businesses

    View Slide

  17. your old school desktop app

    View Slide

  18. what we started with
    Client
    LAN/SQL
    Database
    Desktop
    Application

    View Slide

  19. Goal
    A remote service that client apps can leverage to stay in sync withc each other

    View Slide

  20. What we need #1
    Must be accessible by any kind of client technology

    View Slide

  21. What we need #2
    Abstract the data access layer
    so we can update/replace the engine at any time with no impact on clients

    View Slide

  22. What we need #3
    An appropriate data storage engine

    View Slide

  23. What we need #4
    Easily (re)deployable and scalable multi-micro-service architecure

    View Slide

  24. Where we want to go
    Clients
    “Cloud”
    Database
    RESTful
    Web API
    API
    iOS
    Android
    Website
    Desktop Client
    ? ?

    View Slide

  25. Constraints
    • minimum viable product first
    • add features over time
    • frequent database schema updates
    • easily scalable
    • avoid downtime as much as possible
    • cater upfront for a microservices architecture

    View Slide

  26. REST
    So What Is REST All About?

    View Slide

  27. REST is not a standard

    View Slide

  28. REST is not a protocol

    View Slide

  29. REST is an architectural style
    for networked applications

    View Slide

  30. Defines a set of simple principles
    loosely followed by most API implementations

    View Slide

  31. “resource”
    the source of a specific information

    View Slide

  32. A web page is not a resource
    rather the representation of a resource

    View Slide

  33. “global permanent identifier”
    every resource is uniquely identified. Think a HTTP URI.

    View Slide

  34. #3
    standard interface
    used to exchange representations of resources
    (think the HTTP protocol)

    View Slide

  35. “a set of constraints”
    separation of concerns, stateless, cacheability, layered system, uniform interface, etc.

    View Slide

  36. Web is built on REST
    and it is meant to be consumed by humans

    View Slide

  37. RESTful APIs are built on REST
    and are meant to be consumed by machines

    View Slide

  38. Representational State Transfer (REST)
    by Roy Thomas Fielding
    http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

    View Slide

  39. Goals #1 and #2 are met
    REST layer allows all kinds of client technologies and abstracts the data away

    View Slide

  40. MongoDB and REST
    Or why we picked MongoDB for our REST API

    View Slide

  41. JSON transport
    Most REST services and clients produce and consume use JSON

    View Slide

  42. JSON-style data store
    MongoDB stores data as Binary JSON

    View Slide

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

    View Slide

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

    View Slide

  45. JSON & RESTful API
    JSON
    objects
    Client
    JSON
    (BSON)
    Mongo
    JSON/dict
    maps to python dict
    (validation layer)
    API
    POST
    also works when sending data the database

    View Slide

  46. Similarity with RDBMS
    makes NoSQL easy to grasp (even for a sql head like me)

    View Slide

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

    View Slide

  48. What about Queries?
    Queries in MongoDB are represented as JSON-style objects
    db.things.find({x: 3, y: "foo”});

    View Slide

  49. Filtering and Sorting
    native
    Mongo
    query syntax
    Client
    JSON
    (BSON)
    Mongo
    (very) thin
    parsing
    & validation
    layer
    API
    Expose the native MongoDB syntax?
    ?where={“x”: 3, “y”: “foo”}

    View Slide

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

    View Slide

  51. No need for ORM
    No need to map objects to JSON and vice-versa (win!)

    View Slide

  52. schema-less
    dynamic documents allow for painless evolution

    View Slide

  53. REST is stateless
    MongoDB lacks transactions

    View Slide

  54. Ideal API Surface
    Mongo collection maps to API resource endpoint
    api.example.com/contacts
    Maps to a Mongo collection

    View Slide

  55. Ideal API Surface
    Mongo document maps to a API document endpoint
    api.example.com/contacts/4f46445fc88e201858000000
    Maps to a collection ObjectID

    View Slide

  56. Goal #3 is met
    An appropriate data storage engine: MongoDB

    View Slide

  57. Eve
    REST API for Humans™
    Free and Open Source
    Powered by MongoDB and Good Intentions
    eve

    View Slide

  58. Philosopy
    effortlessly build and deploy highly customizable, fully featured
    RESTful Web Services

    View Slide

  59. Quickstart

    View Slide

  60. install
    $ pip install eve

    View Slide

  61. run.py
    from eve import Eve
    app = Eve()
    if __name__ == '__main__':
    app.run()

    View Slide

  62. settings.py
    # just a couple API endpoints with no custom
    schema or rules.
    DOMAIN = {
    ‘people’: {}
    ‘works’: {}
    }

    View Slide

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

    View Slide

  64. enjoy
    HATEOAS AT WORK HERE
    $ curl http://localhost:5000/people
    {
    "_items": [],
    "_links": {
    "self": {"href": "people", "title": "people"},
    "parent": {“href": "/", "title": "home"},
    },
    "_meta": {
    "max_results": 25,
    "total": 0,
    "page": 1
    }}

    View Slide

  65. enjoy
    CLIENTS CAN
    EXPLORE THE API
    PROGRAMMATICALLY
    $ curl http://localhost:5000/people
    {
    "_items": [],
    "_links": {
    "self": {"href": "people", "title": "people"},
    "parent": {“href": "/", "title": “home”}
    },
    "_meta": {
    "max_results": 25,
    "total": 0,
    "page": 1
    }}

    View Slide

  66. $ curl http://localhost:5000/people
    {
    "_items": [],
    "_links": {
    "self": {"href": "people", "title": "people"},
    "parent": {“href": "/", "title": "home"},
    },
    "_meta": {
    "max_results": 25,
    "total": 0,
    "page": 1
    }}
    enjoy
    AND EVENTUALLY FILL THE UI

    View Slide

  67. enjoy
    $ curl http://localhost:5000/people
    {
    "_items": [],
    "_links": {
    "self": {"href": "people", "title": "people"},
    "parent": {“href": "/", "title": "home"},
    },
    "_meta": {
    "max_results": 25,
    "total": 0,
    "page": 1
    }}
    PAGINATION DATA

    View Slide

  68. enjoy
    EMTPY RESOURCE
    AS WE DID NOT
    CONNECT A DATASOURCE
    $ curl http://localhost:5000/people
    {
    "_items": [],
    "_links": {
    "self": {"href": "people", "title": "people"},
    "parent": {“href": "/", "title": "home"},
    },
    "_meta": {
    "max_results": 25,
    "total": 0,
    "page": 1
    }}

    View Slide

  69. settings.py
    # let’s connect to a mongo instance
    MONGO_HOST = 'localhost'
    MONGO_PORT = 27017
    MONGO_USERNAME = 'user'
    MONGO_PASSWORD = 'user'
    MONGO_DBNAME = 'percona'

    View Slide

  70. settings.py
    # let’s also add a few validation rules
    DOMAIN['people']['schema'] = {
    'name': {
    'type': 'string’,
    'maxlength': 50,
    'unique': True},
    'email': {
    'type': 'string',
    'regex': '^\[email protected]\S+$'},
    'location': {
    'type': 'dict',
    'schema': {
    'address': {'type': 'string'},
    'city': {'type': 'string’}}},
    'born': {'type': 'datetime'}}
    UNIQUE STRING,
    MAX LENGTH 50

    View Slide

  71. settings.py
    # let’s also add a few validation rules
    DOMAIN['people']['schema'] = {
    'name': {
    'type': 'string',
    'maxlength': 50,
    'unique': True},
    'email': {
    'type': 'string',
    'regex': '^\[email protected]\S+$'},
    'location': {
    'type': 'dict',
    'schema': {
    'address': {'type': 'string'},
    'city': {'type': 'string’}}},
    'born': {'type': 'datetime'}}
    ONLY ACCEPT
    VALID EMAILS

    View Slide

  72. settings.py
    # let’s also add a few validation rules
    DOMAIN['people']['schema'] = {
    'name': {
    'type': 'string’,
    'maxlength': 50,
    'unique': True},
    'email': {
    'type': 'string',
    'regex': '^\[email protected]\S+$'},
    'location': {
    'type': 'dict',
    'schema': {
    'address': {'type': 'string'},
    'city': {'type': 'string’}}},
    'born': {'type': 'datetime'}}
    THIS REGEX SUCKS!

    DON’T USE
    IN PRODUCTION

    View Slide

  73. settings.py
    # let’s also add a few validation rules
    DOMAIN['people']['schema'] = {
    'name': {
    'type': 'string',
    'maxlength': 50,
    'unique': True},
    'email': {
    'type': 'string',
    'regex': '^\[email protected]\S+$'},
    'location': {
    'type': 'dict',
    'schema': {
    'address': {'type': 'string'},
    'city': {'type': 'string’}}},
    'born': {'type': 'datetime'}}
    SUBDOCUMENT WITH
    2 STRING FIELDS

    View Slide

  74. settings.py
    # let’s also add a few validation rules
    DOMAIN['people']['schema'] = {
    'name': {
    'type': 'string’,
    'maxlength': 50,
    'unique': True},
    'email': {
    'type': 'string',
    'regex': '^\[email protected]\S+$'},
    'location': {
    'type': 'dict',
    'schema': {
    'address': {'type': 'string'},
    'city': {'type': 'string’}}},
    'born': {'type': 'datetime'}}
    ONLY ACCEPT
    DATETIME VALUES

    View Slide

  75. settings.py
    # allow write access to API endpoints
    # (default is [‘GET’] for both settings)
    # /people
    RESOURCE_METHODS = ['GET','POST']
    # /people/
    ITEM_METHODS = ['GET','PATCH','PUT','DELETE']
    ADD/CREATE ONE OR MORE ITEMS

    View Slide

  76. settings.py
    # allow write access to API endpoints
    # (default is [‘GET’] for both settings)
    # /people
    RESOURCE_METHODS = ['GET','POST']
    # /people/
    ITEM_METHODS = ['GET','PATCH','PUT','DELETE']
    EDIT ITEM

    View Slide

  77. settings.py
    # allow write access to API endpoints
    # (default is [‘GET’] for both settings)
    # /people
    RESOURCE_METHODS = ['GET','POST']
    # /people/
    ITEM_METHODS = ['GET','PATCH','PUT','DELETE']
    REPLACE ITEM

    View Slide

  78. settings.py
    # allow write access to API endpoints
    # (default is [‘GET’] for both settings)
    # /people
    RESOURCE_METHODS = ['GET','POST']
    # /people/
    ITEM_METHODS = ['GET','PATCH','PUT','DELETE']
    YOU GUESSED IT

    View Slide

  79. settings.py
    CLIENT UI
    # a few optional 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'}
    }
    }
    )

    View Slide

  80. settings.py
    CLIENT CACHE OPTIONS
    # a few optional 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'}
    }
    }
    )

    View Slide

  81. settings.py
    ALTERNATE ENDPOINT
    # a few optional 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'}
    }
    }
    )

    View Slide

  82. Features Overview
    We are going to focus on MongoDB power-ups

    View Slide

  83. full range of CRUD operations
    Create/POST
    Read/GET
    Update/PATCH and Replace/PUT
    Delete/DELETE

    View Slide

  84. filters, mongo style
    ?where={“name”: “john”}

    View Slide

  85. filters, the python way
    ?where=name==john

    View Slide

  86. sorting
    ?sort=city,-name
    SORT BY CITY, THEN NAME DESCENDING

    View Slide

  87. projections
    ?projection={"avatar": 0}
    RETURN ALL FIELDS BUT ‘AVATAR’

    View Slide

  88. projections
    ?projection={"lastname": 1}
    ONLY RETURN ‘LASTNAME’

    View Slide

  89. pagination
    ?max_results=20&page=2
    MAX 20 RESULTS PER PAGE; PAGE 2

    View Slide

  90. GeoJSON
    support and validation for all GeoJSON types
    Point, LineString, Polygon, MultiPoint,
    MultiLineString, MultiPolygon, GeometricalCollection

    View Slide

  91. document embedding
    joins

    View Slide

  92. standard request
    $ curl example.com/works/
    {

    "title": "Book Title",

    "description": "book description",

    "author": “52da465a5610320002660f94"

    }
    RAW FOREIGN KEY
    (DEFAULT)

    View Slide

  93. request an embedded document
    $ curl example.com/works/?embedded={“author”: 1}
    {

    "title": "Book Title",

    "description": "book description",

    "author": {

    “firstname”: “Mark”,

    “lastname”: “Green”,

    }

    }
    REQUEST EMBEDDED AUTHOR

    View Slide

  94. embedded document
    $ curl example.com/works/?embedded={“author”: 1}
    {

    "title": "Book Title",

    "description": "book description",

    "author": {

    “firstname”: “Mark”,

    “lastname”: “Green”,

    }

    }
    # embedding is configurable on per-field basis and
    # can be pre-set by API maintainer
    EMBEDDED DOCUMENT

    View Slide

  95. bulk inserts
    insert multiple documents with a single request

    View Slide

  96. request
    $ curl -d ‘
    [
    {
    "firstname": "barack",
    "lastname": “obama"
    },
    {
    "firstname": "mitt",
    "lastname": “romney”
    }
    ]'
    -H 'Content-Type: application/json’

    View Slide

  97. response
    [
    {
    "_status": "OK",
    "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
    "_id": "50ae43339fa12500024def5b",
    "_etag": "749093d334ebd05cf7f2b7dbfb7868605578db2c"
    "_links": {"self": {"href": “”, "title": "person"}}
    },
    {
    "_status": "OK",
    "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
    "_id": "50ae43339fa12500024def5c",
    "_etag": "62d356f623c7d9dc864ffa5facc47dced4ba6907"
    "_links": {"self": {"href": “", "title": "person"}}
    }
    ] COHERENCE MODE OFF: ONLY META FIELDS ARE RETURNED

    View Slide

  98. response
    [
    {
    "_status": "OK",
    "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
    "_id": "50ae43339fa12500024def5b",
    "_etag": "749093d334ebd05cf7f2b7dbfb7868605578db2c"
    "_links": {"self": {"href": “”, "title": “person”}},
    "firstname": "barack",
    "lastname": "obama",
    },
    {
    "_status": "OK",
    "_updated": "Thu, 22 Nov 2012 15:22:27 GMT",
    "_id": "50ae43339fa12500024def5c",
    "_etag": "62d356f623c7d9dc864ffa5facc47dced4ba6907"
    "_links": {"self": {"href": “", "title": "person"}}
    "firstname": "mitt",
    "lastname": "romney",
    }
    ]
    COHERENCE MODE ON: ALL FIELDS RETURNED

    View Slide

  99. document versioning
    ?version=3
    ?version=all
    ?version=diffs

    View Slide

  100. soft deletes
    preserve deleted documents and retrieve them with a simple
    ?show_deleted

    View Slide

  101. file storage
    files are stored in GridFS by default; customizable for S3, file system, etc.

    View Slide

  102. data validation
    powerful and extensible data validation powered by Cerberus

    View Slide

  103. rich validation grammar
    referentrial integrity / unique values / defaults / regex / etc.

    View Slide

  104. custom data types
    create your own data types to validate against

    View Slide

  105. custom validation logic
    extended the validation system to cater for specific use cases

    View Slide

  106. multi database
    serve endpoints and/or users from dedicated mongos

    View Slide

  107. index maintenance
    define sets of resource indexes to be (re)created at launch
    supports sparse, geo2d and background indexes

    View Slide

  108. event hooks
    plug custom actions in the request/response cycle

    View Slide

  109. run.py
    from eve import Eve
    app = Eve()
    def percona(resource, response):
    documents = response['_items']
    for document in documents:
    document['percona'] = 'is so cool!'
    if __name__ == '__main__':
    app.on_fetched_resource += percona_live
    app.run()
    CALLBACK FUNCTION

    View Slide

  110. run.py
    from eve import Eve
    app = Eve()
    def percona(resource, response):
    documents = response['_items']
    for document in documents:
    document['percona'] = 'is so cool!'
    if __name__ == '__main__':
    app.on_fetched_resource += percona_live
    app.run()
    LOOP ON ALL DOCUMENTS

    View Slide

  111. run.py
    from eve import Eve
    app = Eve()
    def percona(resource, response):
    documents = response['_items']
    for document in documents:
    document['percona'] = 'is so cool!'
    if __name__ == '__main__':
    app.on_fetched_resource += percona_live
    app.run()
    INJIECT FIELD

    View Slide

  112. run.py
    from eve import Eve
    app = Eve()
    def percona(resource, response):
    documents = response['_items']
    for document in documents:
    document['percona'] = 'is so cool!'
    if __name__ == '__main__':
    app.on_fetched_resource += percona_live
    app.run()
    ATTACH CALLBACK TO
    EVENT HOOK

    View Slide

  113. rate limiting
    powered

    View Slide

  114. settings.py
    # Rate limit on GET requests:
    RATE_LIMIT_GET = (1, 60)
    ONE REQUEST PER MINUTE (CLIENT)

    View Slide

  115. $ curl -i
    HTTP/1.1 200 OK
    X-RateLimit-Limit: 1
    X-RateLimit-Remaining: 0
    X-RateLimit-Reset: 1390486659
    rate limited request
    CURRENT LIMIT

    View Slide

  116. $ curl -i
    HTTP/1.1 200 OK
    X-RateLimit-Limit: 1
    X-RateLimit-Remaining: 0
    X-RateLimit-Reset: 1390486659
    rate limited request
    REMAINING

    View Slide

  117. $ curl -i
    HTTP/1.1 200 OK
    X-RateLimit-Limit: 1
    X-RateLimit-Remaining: 0
    X-RateLimit-Reset: 1390486659
    rate limited request
    TIME TO RESET

    View Slide

  118. $ curl -i
    HTTP/1.1 429 TOO MANY REQUESTS
    rate limited request
    OUCH!

    View Slide

  119. operations log
    log all operations and eventually expose a dedicated endpoint

    View Slide

  120. HATEOAS
    Hypermedia As Engine Of The Application State

    View Slide

  121. XML support
    $ curl -H ”Accept: application/xml” -i http://example.com/people



    <_created>Fri, 18 Sep 2015 13:41:37 GMT
    <_etag>5d057712ce792ebb4100b96aa98bfe9b6693c07b
    <_id>55fc149138345b0880f07e3d
    <_updated>Fri, 18 Sep 2015 13:41:37 GMT
    [email protected]
    john


    View Slide

  122. conditional requests
    allow clients to only request non-cached content

    View Slide

  123. If-Modified-Since
    If-Modified-Since: Wed, 05 Dec 2012 09:53:07 GMT
    ONLY RETURN DOCUMENT IF MODIFIED SINCE

    View Slide

  124. If-None-Match
    If-None-Match:1234567890123456789012345678901234567890
    >
    ONLY RETURN DOCUMENT ETAG CHANGED

    View Slide

  125. data integrity and concurrency
    no overwriting documents with obsolete versions

    View Slide

  126. missing ETag
    # fails, as there is no ETag included with request
    $ curl \
    -X PATCH \
    -i http://example.com/people/521d6840c437dc0002d1203c \
    -H "Content-Type: application/json" \
    -d '{"name": “ronald"}'
    HTTP/1.1 403 FORBIDDEN
    NO ETAG
    REJECTED

    View Slide

  127. ETag mismatch
    # fails, as ETag does not match with server
    $ curl \
    -X PATCH \
    -i http://example.com/people/521d6840c437dc0002d1203c \
    -H "If-Match: 1234567890123456789012345678901234567890" \
    -H "Content-Type: application/json” \
    -d '{"firstname": "ronald"}'
    HTTP/1.1 412 PRECONDITION FAILED
    ETAG MISMATCH
    REJECTED

    View Slide

  128. valid ETag
    # success at last! ETag matches with server
    $ curl \
    -X PATCH \
    -i http://example.com/people/50adfa4038345b1049c88a37 \
    -H "If-Match: 80b81f314712932a4d4ea75ab0b76a4eea613012" \
    -H "Content-Type: application/json" \
    -d '{"firstname": "ronald"}'
    HTTP/1.1 200 OK
    # Like most of features, ETags can be disabled.
    ETAG MATCH
    ACCEPTED

    View Slide

  129. custom data layers
    build your own data layer

    View Slide

  130. authentication and authorization
    basic / token / hmac / BYO / OAuth2 / you name it

    View Slide

  131. and (a lot) more
    CORS, cache control, API versioning, JOSNP, Etc.

    View Slide

  132. vibrant community
    90+ contributors / 350+ forks / 2500+ github stargazers

    View Slide

  133. Eve-Docs
    automatic documentation for Eve APIs in both HTML and JSON
    CHARLES FLYNN

    View Slide

  134. Eve-Docs

    View Slide

  135. Eve-Elastic
    Elasticsearch data layer for your Eve-powered API
    PETR JASEK

    View Slide

  136. Eve-SQLAlchemy
    SQL data layer for Eve-powered APIs
    PETR JASEK

    View Slide

  137. Eve-Mongoengine
    enables mongoengines data models to be used as Eve schema
    STANISLAV HELLER

    View Slide

  138. Eve.NET
    HTTP and REST client for Eve-powered APIs
    PETR JASEK

    View Slide

  139. Eve-OAuth2
    leverage Flask-Sentinel to protect your API endpoints with OAuth2
    THOMAS SILEO

    View Slide

  140. REST Layer
    “golang REST API framework heavily inspired by Python Eve”
    THOMAS SILEO

    View Slide

  141. Goal # 4 achieved
    easy to setup, launch and scale up; also a good fit for microservices infrastracture

    View Slide

  142. A look back to initial draft
    Clients
    “Cloud”
    Database
    RESTful
    Web API
    API
    iOS
    Android
    Website
    Desktop Client
    ? ?

    View Slide

  143. Clients
    Multiple
    MongoDBs
    Database
    Adam
    eve instances
    API
    iOS
    Android
    Website
    Desktop Client
    what we have in production

    View Slide

  144. stories from the trenches
    #1. when too much (magic) is too much
    #2. sometimes you don’t want to debug
    #3. so how do I login into this thing?

    View Slide

  145. Take Aways

    View Slide

  146. Enhance MongoDB
    with powerful features on top of native engine
    validation, document embedding (joins), referential integrity,
    document versioning, transformations, rate limiting, etc.

    View Slide

  147. Consider the REST layer
    as an ideal data access layer
    the story of pymongo 3.0 breaking changes
    mongo or sql or elastic or …

    View Slide

  148. Consider the REST layer
    as an ideal data access layer
    the story of Adam dashboards

    View Slide

  149. Consider Microservices
    leverage Eve features create a network of isolated yet standardized services

    each service has a dedicated role
    runs as an eve instance, with its own configuration
    has its own database(s)
    callbacks route traffic between services

    View Slide

  150. Clients
    User-reserved
    MongoDBs
    eve-multidb
    Data
    Auth
    eve-oauth2
    (flask-sentinel)
    API
    iOS
    Android
    Website
    Desktop Client
    Adam 1
    Adam
    eve instance
    Redis
    auth tokens,
    rate limiting
    Auth/Users
    MongoDB

    View Slide

  151. Clients
    service-
    reserved
    MongoDBs
    Data
    Auth
    eve-oauth2,
    flask-sentinel
    API
    iOS
    Android
    Website
    Desktop Client
    Adam 2
    Adam
    eve instance
    Redis
    auth tokens,
    rate limiting
    Services
    eve instances
    Auth/Users
    MongoDB
    very simplified

    View Slide

  152. thanks
    nicolaiarocci
    python-eve.org
    eve

    View Slide