Search code examples
pythonrestflaskmongoenginehateoas

Marshmallow URLFor BuildError with ObjectId


How can I make my RESTFul API HATEOAS with MongoEngine and Flask-Marshmallow?

I'm using

class PraiaSerializer(ma.Schema):                                                                                                      
    id = ma.String()                                                                                                                   
    atividades = ma.Nested(AtividadeSerializer, many=True)                                                                             

    class Meta:                                                                                                                        
        additional = ('nome', 'descricao', '_links')                                                                                   

    _links = ma.Hyperlinks({                                                                                                           
        'self': ma.URLFor('praia_detail', id='<id>'),                                                                                  
        'collection': ma.URLFor('praias')                                                                                              
    })               

But, when sending a request to my route, marshmallow throws a BuildError.

BuildError: ('atividade_detail', MultiDict([('id', ObjectId('55024fdfe138235aeac01380'))]), None)

What should I do?

Am I passing something wrong to my ma.Hyperlinks?


Solution

  • Solved my problem!

    I'm using Flask-RESTFul to write my API, so I had to register my routes with an endpoint name. In case of using pure Flask, use your function names.

    api.add_resource(PraiaListView, '/v1/praias', endpoint='praias_resource')
    api.add_resource(PraiaView, '/v1/praias/<id>', endpoint='praia_detail')
    

    and use:

    _links = ma.Hyperlinks({                                                                                                           
            'self': ma.URLFor('praia_detail', id='<id>'),                                                                                  
            'collection': ma.URLFor('praias_resource')                                                                                              
        })    
    

    so marshmallow could generate this output for the _links field:

    "_links": {
      "collection": "/v1/praias",
      "self": "/v1/praias/55025029e138235aeac01383"
    },