samedi 7 février 2015

Ember-Data RESTSerializer for BSON API

So I have an API built with Flask and MongoDB (using MongoEngine), that contains two routes: /resources and /resources/<resource_id>. The default behavior is to serve BSON data, like such:



{
"_id": {
"$oid": "54cb3c35b53e1bc76f1eefb3"
},
"message": "Hello World!"
}


Now, my front-end is based on Ember + Ember-Data. The RESTSerializer does not support BSON by default. I believe I have two options:



  1. Handle the BSON format on the client side

  2. Have the API serve JSON, i.e. replace {"_id": {"$oid": "54..."}} with {"_id": "54..."}


For the first option, I could hack the application serializer to create a property "id" that contains the objectId as a string:



// app/serializers.application.js
export default DS.RESTSerializer.extend({
normalizeHash: {
resource: function(hash){
hash.id = hash['_id']['$oid'];
delete hash['_id'];
return hash;
}
}
});


That works, but as far as I understand, normalizeHash is model-specific and so I would have to define normalizeHash.modelName for all models in my app.


Note that setting primaryKey to _id is not enough (it would be if the API served something like: {"_id": "54cb..."}.


I suppose I could also use normalizePayload, but I would have to handle a variety of cases — in general it will be either a single object or an array of objects wrapped in a dictionary.


Is there a simpler way to handle the serialization client-side?


Things are more complicated with the second option. Right now, my views look like this:



@app.route("/<resource_id>")
def get_resource(resource_id):
resource = Resource.objects.get_or_404(id=resource_id)
return flask.jsonify(resource=resource)

@app.route("/")
def get_resources():
resources = Resource.objects.all()
return flask.jsonify(resources=resources)


I would like for these views to remain as simple as possible.


The first route can be sort-of-easily fixed, by subclassing MongoEngine's Document class and overriding the to_json method.


The second route is more complicated. The JSON serialization is defined in the Queryset class (which is the type of Resource.objects.all()), overriding it would require much more work (and it feels messy).


Is there a simple way to tweak the serialization on the server side that would be compatible with my writing of the views (or a minimal rewriting of them)?


Thanks in advance!





Aucun commentaire:

Enregistrer un commentaire