Relationships + Includes mapping
lukewakeford opened this issue ยท 5 comments
Hey, I'm using this framework to add support for a new JSON:API endpoint/feature to an existing project with many other features that use Codable models with HAL+JSON format. so far so good, really appreciate the hard work put in to this framework ๐๐ป it's enabled me to slot the new feature in and re-use our existing Codable networking setup which is awesome!.
Similarly to #43 I've got so far implementing a batch document and was looking for the simplest way to access relationships/includes. (I'm used to doing this with dot syntax since we've been using HAL+JSON up to this point, where relationships are embedded in to primary resources giving direct access to those full objects) For now with JSONAPI it looks like the best way to do this is to filter or look up includes by id?
In the same vein after implementing includes I couldn't help but wonder why we have to define the number of includes BatchDocument<Person, Include2<Dog, Cat>>
when these are already defined as JSONAPI.Relationships
in our ResourceObjectDescription
enum PersonDescription: ResourceObjectDescription {
static var jsonType: String = "person"
struct Attributes: JSONAPI.Attributes {
let name: Attribute<String>
}
struct Relationships: JSONAPI.Relationships {
let dogs: ToManyRelationship<Dog, NoIdMetadata, NoMetadata, NoLinks>
let cats: ToManyRelationship<Cat, NoIdMetadata, NoMetadata, NoLinks>
}
}
typealias Person = Resource<PersonDescription>
Thanks again and in advance for any knowledge here. โ๐ป
For now with JSONAPI it looks like the best way to do this is to filter or look up includes by id
This is a reasonably accurate statement. I'll rephrase: JSONAPI
does not offer a built-in way to embed included relationships on the primary resource(s). This is more about not being prescriptive than anything else.
If your project uses a store
to cache all resources, you actually don't want related resources directly embedded on primary resources, you want to store everything in the cache and know you are looking up the latest versions of each thing from your store
each time you need them. It's possible to use this kind of setup conveniently, but it may require some machinery built outside of JSONAPI
(and that machinery wouldn't be one-size-fits all in that there are any number of ways to implement a cache of resources).
If your project instead wants to consider each JSON:API response as a complete picture of some resources, I agree that the JSONAPI
library leaves something to be desired, but I didn't want to build the library to one use-case or the other (in fact, my use-case was the universal store
model).
Have you had the chance to take a look at the JSONAPIResourceStore
provided by https://github.com/mattpolzin/JSONAPI-ResourceStorage? This was my attempt at providing a starting place (that in some cases might be more than enough) for those wanting to take one or more JSONAPI documents and access resources (including relatives) as if they were one coherent chunk of data. It's not as well documented as the JSONAPI
library, but I would be happy to talk through how it might be helpful to you.
I couldn't help but wonder why we have to define the number of includes
BatchDocument<Person, Include2<Dog, Cat>>
when these are already defined asJSONAPI.Relationships
in ourResourceObjectDescription
It's really just to allow you to be incredibly specific about what is possible. A client can choose to express an API request's result as not offering includes of all the types available on the primary resource if the client is not requesting all of those includes from the server.
I find myself wanting to offer a typealias that simplifies the Document
type in the case that the Includes
and primary resource's Relationships
should represent the same types of things, but I'm struggling to come up with a good solution. I think Swift's type-level programming might not be strong enough to make this task as easy as I'd like it to be.
Regarding using JSONAPI-ResourceStorage
, I think the convenience you are after is mostly available with the newest release (version 0.4.0). You can specifically take a glance at how the new example test digs into a primary resource and its relatives as if the relatives were directly embedded in the primary resource: https://github.com/mattpolzin/JSONAPI-ResourceStorage/blob/0.4.0/Tests/JSONAPIResourceStoreTests/SingleResponseExample.swift#L133..L143
Thats great thanks for taking the time to reply ๐๐ป
I'm going to close this as answered, but anyone can feel free to follow up if a question in the same vein comes into focus!