Search code examples
pythoneve

In Eve, what is the difference between inserting a document into a collection using the http method POST and using the mongo shell?


Background Information

The answer to my previous question (In Eve, how can you make a sub-resource of a collection and keep the parent collections endpoint?) was to use the multiple endpoints, one datasource feature of Eve. In the IRC channel, I was speaking with cuibonobo, and she was able to get this working by changing the game_id to be an objectid instead of a string, as shown here:

http://gist.github.com/uunsamp/d969116367181bb30731

I however didn't get this working, and as you can see from the conversation, I was putting documents into the collection differently:

14:59 < cuibonobo> no. it's just that since your previous settings file saved the game id as a string, the lookup won't work

15:00 < cuibonobo> it will only work on documents where game_id has been saved as an ObjectId

15:01 < cuibonobo> the way Eve currently works, if you set the type to 'objectid', it will convert the string to a Mongo ObjectId before saving it in the database. but that conversion doesn't happen with strings

15:02 < znn> i haven't been using eve for storing objects

15:02 < znn> i've been using the mongo shell interface for inserting items

15:03 < cuibonobo> oh. hmm. that might complicate things. Eve does type conversions and other stuff before inserting documents.

15:04 < cuibonobo> so inserting stuff directly into mongo generally isn't recommended

Question Which leads me to stackoverflow :)

What is the difference between inserting a document into a collection using the http method POST and using the mongo shell? Will users eventually be able to use either method of document insertion?

Extra information

I was looking through http://github.com/nicolaiarocci/eve/blob/develop/eve/methods/post.py before asking this question, but this could take awhile to understand, much longer than just asking someone who maybe is more familiar with the code than myself.


Solution

  • The quick answer is that Eve is adding a few meta fields etag, updated, created along with every stored document. If you want to store documents locally (not going through HTTP) you can use post_internal:

    Intended for internal post calls, this method is not rate limited,
    authentication is not checked and pre-request events are not raised.
    Adds one or more documents to a resource. Each document is validated
    against the domain schema. If validation passes the document is inserted
    and ID_FIELD, LAST_UPDATED and DATE_CREATED along with a link to the
    document are returned. If validation fails, a list of validation issues
    is returned.
    

    Usage example:

    from run import app
    from eve.methods.post import post_internal
    
    payload = {
        "firstname": "Ray",
        "lastname": "LaMontagne",
        "role": ["contributor"]
    }
    
    with app.test_request_context():
        x = post_internal('people', payload)
        print(x)
    

    Documents inserted with post_internal are subject to the same validation and will be stored like they were by API clients via HTTP. In 0.5-dev (not released yet) PATCH, PUT and DELETE internal methods have been added too.