I have a simple db model which references itself, to create a hierarchical structure.
Now I want to build a RESTapi, using Flask, Flask-SQLAlchemy and Flask-marshmallow.
For convenience reasons I inheriet my Schema-classes from ma.SQLAlchemyAutoSchema
(where ma
is the instance of flask-marshmallow)
If the model has children, I want my endpoint to return the category object, including a link to the endpoint that returns the children. (which works fine.) But if the model has no children, the link shall not be included.
My gut feeling tells me that you could and and probably should set this directly in the schema definition.
#model.py
from app import db
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, index=True)
parent_id = db.Column(db.Integer, db.ForeignKey("category.id", ondelete="SET NULL"))
children = db.relationship("Category",
backref=db.backref('parent', remote_side=[id]),
lazy="dynamic")
#schema.py
from app import model, ma, db
class CategorySchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = model.Category
_links = ma.Hyperlinks({
'children': ma.URLFor('api.category_children', equipment_id="<id>")
if model.Category.query.filter_by(id=??????).first().children.first() else None
})
I came up with the simple ternary assignment above, but I can not figure out, where to get the id (id=??????
) from, (which is the very same id that ma.URLFor()
accesses via equipment_id="<id>"
).
expected example output, if children exist
{
"_links": {
"children": "/api/v1/category/1/children"
},
"id": 1,
"name": "some_name"
}
expected example output, if no children exist:
{
"_links": {
"children": null
},
"id": 1,
"name": "some_name"
}
thank you in advance
I think you're over engineering your design. Just having:
class CategorySchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = model.Category
_links = ma.Hyperlinks({
'children': ma.URLFor('api.category_children', equipment_id="<id>")
})
should be fine. If the Parent has no Children, then hitting the endpoint (in your example) of "/api/v1/category/1/children"
should just return an empty result set. You shouldn't need to control the navigation links they way you've described. The expectation from HATEOAS design is you should be able to navigate consistently through the resources to the desired endpoint. Having to deal with a null
value for a link rather than an empty result, IMO is setting yourself for a headache down the line.
Otherwise, if you really want/need to. The post_dump
decorator should give you access to find the id
value.