The jsonapi.org serializers in JS right now are not great.
They don't account well for includes
, fields
, attribute
definitions, relations
definitions.
Denali does handle jsonapi.org well but the serialization is coupled to rest of the framework.
json-api-serializer
has type registrations but does not handle request options like sparsefieldsets or includes.
I think the API provided for json-api-serializer
is close but to add support for the missing options I think a new API should be changed a bit.
The json-api-serializer
Serialize API is serialize(type, data, meta)
.
While this is more flexible than some other frameworks, it does limit some use.
Instead a new API should be serialize(type: string, { data, meta }, request: Request?)
this would allow the serializer to respond to requests and extract things like fields
and includes
to send back proper responses.
The request could also be used to make links
into full URLs if relative links were provided.
In order to enable the serializer to work with different routers, ORMs, and more: an adapter pattern should be used.
For instance an ExpressRequestAdatper
would extend from RequestAdapter:
import _ from 'lodash';
class ExpressRequestAdapter extends RequestAdatper {
getFields(request: Request) : { [type:string] : {fields: string[]} } {
return _.mapValues(request.query.fields, a => a.split(','));
},
getInclude(request: Request) : string[] {
return request.query.include.split(',');
},
getData(request: Request) : JsonApiDocument {
return request.body.data;
}
}
Another thought is to use adapters for getting ids and turning them into data keys for example taking relationships.author.data.id
and turning it into author_id
.
The alternativeKey
will work for most usecases, but it is a thought to be able to adapt and better integrate with the data expected by ORMs.
With deserialize I think there's an approach where unconvertCase
is actually something done in an adapter or middleware instead of using a config option to the deserialize function itself.
deserialize(request: Request, type: string?)
The type when deserializing would be optional.