Comments (8)
Hi @sartian,
Actually serialize functions only support serialization of one type at time, and there is no way to serialize multiple types at once.
We could had a function with an option that will look at a reference path in data to determine which type to use to serialize.
Each object should have the same reference path to determine the type to use.
[{
type: 'articles',
title: 'First article'
},
{
type: 'books',
title: 'First books'
}
// ...
]
Then (proposal) :
Serializer.serialize({
refPath: 'type', // the reference path to look to determine which type to use to serialize
topLevelMeta: function(extraOptions) {
return {
count: extraOptions.count,
total: extraOptions.total
}
},
topLevelLinks: {}
}, data, extraOptions)
@Mattii any thoughts ?
from json-api-serializer.
That sounds like an approach that could work, I am guessing the parameter is named 'refPath' instead of 'type' due to links creation? Hrm. To make it elegant from a data perspective maybe there could be a type and typePathMappings (?got a better name?). With type mappings the type could be specified on the entry itself and the map would indicate resource path to use. (I'm new to this api, apologies of it already has support for that in some capacity). Like mappings of {'book': 'books', 'article': 'articles', 'review': 'reviews'}.
If we had an data back-end that kept references of books and articles affiliated with certain authors and we exposed it for searching it like so:
http://localhost:3000/search?q=neil+gaiman&page[offset]=0&page[limit]=3
...the raw unserialized hits returned from a back-end datastore might look like this:
[{
"id": 14,
"type": "article",
"authors": [ "Neil Gaiman"],
"title": "Neil Gaiman: ‘Terry Pratchett isn’t jolly. He’s angry’",
"url": "https://www.theguardian.com/books/2014/sep/24/terry-pratchett-angry-not-jolly-neil-gaiman"
},
{
"id": 37,
"type": "review",
"book": "Good Omens",
"authors": [ "Neil Gaiman", "Terry Pratchett" ],
"title": "Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch",
"url": "http://www.goodreads.com/book/show/12067.Good_Omens"
},
{
"id": 15,
"type": "book",
"book": "American Gods",
"authors": [ "Neil Gaiman" ],
"title": "Neil Gaiman | Neil's Work | Books | American Gods",
"url": "http://www.neilgaiman.com/works/Books/American+Gods/"
}]
...whereas the top-level JSON:API serialized response should look something like this:
{
"meta": {
"hits": 3,
"total-hits": 7,
"page": { "offset": 0, "limit": 3 }
},
"data": [
{
"id": 14,
"type": "article",
"attributes": {
"authors": [
"Neil Gaiman"
],
"title": "Neil Gaiman: ‘Terry Pratchett isn’t jolly. He’s angry’",
"url": "https://www.theguardian.com/books/2014/sep/24/terry-pratchett-angry-not-jolly-neil-gaiman"
},
"links": { "self": "/articles/14" }
},
{
"id": 37,
"type": "review",
"attributes": {
"book": "Good Omens",
"authors": [
"Neil Gaiman",
"Terry Pratchett"
],
"title": "Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch",
"url": "http://www.goodreads.com/book/show/12067.Good_Omens"
},
"links": { "self": "/reviews/37" }
},
{
"id": 15,
"type": "book",
"attributes": {
"book": "American Gods",
"authors": [
"Neil Gaiman"
],
"title": "Neil Gaiman | Neil's Work | Books | American Gods",
"url": "http://www.neilgaiman.com/works/Books/American+Gods/"
},
"links": { "self": "/books/15" }
}
],
"links": {
"self": "/search?q=neil+gaiman&page[offset]=0&page[limit]=3",
"first": "/search?q=neil+gaiman&page[offset]=0&page[limit]=3",
"prev": null,
"next": "/search?q=neil+gaiman&page[offset]=3&page[limit]=3",
"last": "/search?q=neil+gaiman&page[offset]=6&page[limit]=3"
}
}
Given this example use case, I'm not sure what is the best approach, maybe a registry of type mapping to resource serializers? From a data design standpoint, when I annotate an object in the system with a type, we want to use the singular form, but for mapping to a resource endpoint that return collections, it makes sense that resource/reference paths use plural version. Thanks!
from json-api-serializer.
'refPath' has nothing to do with links creation. Maybe I have not choose the right name for this parameter. In my first intention if you have register type like this :
Serializer.register('article', options);
Serializer.register('book', options);
Serializer.register('review', options);
And if your data might look like this :
const data = [{
"id": 14,
"type": {
"kind": "article"
},
"authors": ["Neil Gaiman"]
},
{
"id": 37,
"type": {
"kind": "review"
},
"book": "Good Omens",
},
{
"id": 15,
"type": {
"kind": "book"
},
"book": "American Gods",
}]
We could have an option refPath
or pathForType
or whatever, which is the path to look in data to determine dynamically which type to use to serialize. (of course type should be register
before)
Like so :
Serializer.serialize({
pathForType: 'type.kind' // or refPath or whatever
}, data)
Maybe you got a better name ?
from json-api-serializer.
Hi @danivek,
Your suggestion with parameter sounds like a clean way to handle it.
My question about variable naming convention for 'refPath' vs the id variable being called "id" (located here I think: https://github.com/danivek/json-api-serializer/blob/master/lib/JSONAPISerializer.js#L38) and I was just curious why it wouldn't use the name "key". I see this line in optionsSchema:
id: joi.string().default('id'),
...and was curious why (from a design perspective) the next line wouldn't look something like this:
key: joi.string().default(null),
...in this example, it defaults to null as a way to preserve backwards compatibility so it continues to ignore type if included in the data, but if specified the path to the type indicator is adhered to.
I didn't know if there was a particular reason that pathForType
wasn't called key
like the path for id is called id
. In any case, pathForType is a very clear to understand parameter name, thanks! - @sartian
from json-api-serializer.
How could it work if we had this kind of option in options of a resource's type. In other words, what's happen if each type's options define a different "path" ?
How do we call serialize
function ? without first parameter ?
from json-api-serializer.
Interesting use-case, @sartian! I think @danivek's proposal of a object as first parameter is good, but maybe we could make it more flexible by adding a function, which derives the type from each data-item?
Serializer.serialize(item => item.type, data)
Then we could say type
of serialize(type, data)
can be a string or a function deriving a type-string from each data-item. This function can be very sophisticated and determine different types of items.
If that's too cryptic to read, we could wrap it into an object and give it a name.
Serializer.serialize({ type: item => item.type }, data)
from json-api-serializer.
@Mattii Very interesting proposal. I think we also need to redefine 'topLevelMeta' and 'topLevelLink' options when serialize. The second solution with an object is the best way I think (much more customizable).
What about a second function to have an isolated API ?
Serializer.serializeMixed({ type: item => item.type }, data)
from json-api-serializer.
Yes, you're right! For this use-case topLevelMeta
and topLevelLink
can't be defined during registrations of a schema. They need to be defined during serialization.
Putting it into a separate function is fine for me, but we need to take care about keeping the code DRY. The async-serialization already duplicated some logic of the default-serialization. We should definitely open an issue to improve that. But maybe it would be interesting to implement serializeMixed
before, to know all requirements for the shared logic. What about asynchronicity? I would favour it, as everything blocking has the potential to bring up performance issues very soon.
from json-api-serializer.
Related Issues (20)
- ObjectID (mongodb) should be serialized with .toString() and not treated as an object HOT 2
- Support extracting error class names into the 'title' field of JSON API errors HOT 1
- Error when try to deserialise an included relationship with `alternativeKey` HOT 3
- ErrorMaximum call stack size exceeded if `included` has cross references
- Would you be interested in a conversion to Typescript? HOT 2
- Error instance serialization missing properties HOT 1
- ValidationError: beforeSerialize is not allowed HOT 2
- Incorrectly deserializing relationship when alternativeKey is set from default and relationship data is not in the included array HOT 2
- Case conversion breaks on non-alphanumeric strings
- Unintended object in attributes HOT 2
- Is there an option to remove undefined properties? HOT 1
- The result after serialize will not have `included` if the input doesn't have attributes HOT 5
- Error thrown when relationship is not registered HOT 5
- Having no attributes in the relation data does not add relation to included array
- Use a cache for converting to snake/camel/kebab case HOT 1
- bug: When installed in Angular project, it throws error since it is searching for `fs` HOT 3
- Relationships do not work with ES2015 classes
- bug: Duplicated models from includes are removed from response HOT 1
- Support serialization of only meta HOT 2
- Support for relationship data serialization? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from json-api-serializer.