pyeve / eve-sqlalchemy

SQLAlchemy data layer for Eve-powered RESTful APIs
http://eve-sqlalchemy.readthedocs.io
Other
232 stars 70 forks source link

What am I doing wrong with my validation? #83

Closed waynew closed 8 years ago

waynew commented 8 years ago

I have this code and I've got 0.3.4 installed:

root@a784638346e1:/# python -m pip freeze
Cerberus==0.8.1
Eve==0.5.3
Eve-SQLAlchemy==0.3.4
Events==0.2.1
Flask==0.10.1
Flask-PyMongo==0.3.1
Flask-SQLAlchemy==2.1
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
pymongo==2.9
simplejson==3.8.1
SQLAlchemy==1.0.9
Werkzeug==0.10.4

But when I try to post some data:

⚘ curl -X POST http://localdocker:8080/people -d '{"lastname": "Dude"}'                                                                                                 
{"_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}, "_issues": {"{\"lastname\": \"Dude\"}": "unknown field"}, "_status": "ERR"}

Um... Excuse me? Unknown field? lastname is not an unknown field.

Though I wonder about it now... I just changed my validator to this guy:

class PretendValidator(ValidatorSQL):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def validate(self, *args, **kwargs):
        return True

And when I run that it barfs and triggers the debugger which shows me TypeError: '_etag' is an invalid keyword argument for People. Is it just that eve is trying to inject fields? Or what? I've been at this for entirely too long and I think I might be going crazy :P

dkellner commented 8 years ago

I think you just forgot to set the POST's Content-Type. Try this:

⚘ curl -X POST http://localdocker:8080/people -d '{"lastname": "Dude"}' -H 'Content-Type: application/json'

This also explains the error message: It is not complaining about 'lastname' being unknow, but '{\"lastname\": \"Dude\"}' - which is your entire payload.

waynew commented 8 years ago

Ah, right, doh!

So now I guess it validates, but:

TypeError: '_updated' is an invalid keyword argument for People

waynew commented 8 years ago

I guess that's because Eve is trying to provide (require?) metadata... that I don't want. Is there any way around that?

dkellner commented 8 years ago

You're right. Fields like _updated, _created and _etag are automatically handled by Eve. You can change the name, though.

LAST_UPDATED: Name of the field used to record a document’s last update date. This field is automatically handled by Eve. Defaults to _updated. - http://python-eve.org/config.html

Unfortunately, I don't know any way to solve your issue in a clean way. Even if you could modify your models in a way so _updated does not get stored in your db, you might run into problems as Eve supports things like the If-Modified-Since header to query items based on the modification date.

waynew commented 8 years ago

Yeah, I don't think there's a way to get around that, unless eve-sqlalchemy wanted to patch. I think I'll go ask about that on the Eve issue tracker