Flask-restful: marshal complex object to json

I found solution to that problem myself.

After playing around with flask-restful i find out that i made few mistakes:

Firstly set_marshaller should look like this:

set_marshaller = {
    'id': fields.String,
    'title': fields.String,
    'parameters': fields.Nested(parameter_marshaller)
}

Restless marshaller can handle case if parameter is list and marshals to json list.

Another problem was that in API Set parameters has lazy loading, so when i try to marshall Set i got KeyError: 'parameters', so I need explicitly load parameters like this:

class SetApi(Resource):

     @marshal_with(marshallers.set_marshaller)
     def get(self, set_id):
        entity = Set.query.get(set_id)
        entity.parameters # loads parameters from db
        return entity

Or another option is to change model relationship:

parameters = db.relationship("Parameters", backref="set", cascade="all" lazy="joined")

This is an addition to Zygimantas's answer:

I'm using Flask-RESTful and this is a solution to the loading of the nested properties.

You can pass a callable to the marshal decorator:

class OrgsController(Resource):
    @marshal_with(Organization.__json__())
    def get(self):
        return g.user.member.orgs

Then update the models to return the resource fields for its own entity. Nested entities will thus return the resource fields for its entity relatively.

class Organization(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ...

    @staticmethod
    def __json__(group=None):
        _json = {
            'id': fields.String,
            'login': fields.String,
            'description': fields.String,
            'avatar_url': fields.String,
            'paid': fields.Boolean,
        }

        if group == 'flat':
            return _json

        from app.models import Repository
        _json['repos'] = fields.Nested(Repository.__json__('flat'))

        return _json

class Repository(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('organization.id'))
    owner = db.relationship('Organization', lazy='select', backref=db.backref('repos', lazy='select'), foreign_keys=[owner_id])
    ...

    @staticmethod
    def __json__(group=None):
        _json = {
            'id': fields.String,
            'name': fields.String,
            'updated_at': fields.DateTime(dt_format='iso8601'),
        }

        if group == 'flat':
            return _json

        from app.models import Organization
        _json['owner'] = fields.Nested(Organization.__json__('flat'))

        return _json

This gives the representation I'm looking for, and honoring the lazy loading:

[
    {
        "avatar_url": "https://avatars.githubusercontent.com/u/18945?v=3",
        "description": "lorem ipsum.",
        "id": "1805",
        "login": "foobar",
        "paid": false,
        "repos":
            [
                {
                    "id": "9813",
                    "name": "barbaz",
                    "updated_at": "2014-01-23T13:51:30"
                },
                {
                    "id": "12860",
                    "name": "bazbar",
                    "updated_at": "2015-04-17T11:06:36"
                }
            ]
    }
]

I like

1) how this approach allows me to define my resource fields per entity and it is available to all my resource routes across the app.

2) how the group argument allows me to customise the representation however I desire. I only have 'flat' here, but any logic can be written and passed down to deeper nested objects.

3) entities are only loaded as necessary.