Skip to content

Deeply Nested Relationship Inclusion #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jaredcnance opened this issue Feb 28, 2017 · 7 comments
Closed

Deeply Nested Relationship Inclusion #39

jaredcnance opened this issue Feb 28, 2017 · 7 comments
Milestone

Comments

@jaredcnance
Copy link
Contributor

jaredcnance commented Feb 28, 2017

GET /articles/1?include=comments.author HTTP/1.1
Accept: application/vnd.api+json

Note: Because compound documents require full linkage (except when relationship linkage is excluded by sparse fieldsets), intermediate resources in a multi-part path must be returned along with the leaf nodes. For example, a response to a request for comments.author should include comments as well as the author of each of those comments.

Note: A server may choose to expose a deeply nested relationship such as comments.author as a direct relationship with an alias such as comment-authors. This would allow a client to request /articles/1?include=comment-authors instead of /articles/1?include=comments.author. By abstracting the nested relationship with an alias, the server can still provide full linkage in compound documents without including potentially unwanted intermediate resources.

Will also need to include support for Sparse Fieldsets of included relationships

@jaredcnance
Copy link
Contributor Author

Closing. Will consider re-opening if there is demand.

@mattgi
Copy link

mattgi commented Jan 3, 2018

This seems like it would be worthwhile to include? A joining table like comments coming back with only an Author Id means an additional roundtrip from client to server to fetch the user object as well.

Maybe with #218 this could be included too? 🙏

@jaredcnance jaredcnance reopened this Jan 3, 2018
@mattgi
Copy link

mattgi commented Jan 5, 2018

To flesh this out more, given the following 3 entities:

class User {
  string Id { get; set; }
  ...
}

class Item {
  public string Id { get; set; }

  [NotMapped]
  public string StringId { get => this.Id; set => Id = value; }

  [ForeignKey("Owner")]
  [Column("Owner")]
  public string OwnerId { get; set; }

  [HasOne("owner", Link.None)]
  public User Owner { get; set; }

  [NotMapped]
  public ICollection<ItemCollaborator> Collaborators { get; set; }

  [HasMany("collaborators", Link.None)]
  public ICollection<User> Users { get; set; }
}

class ItemCollaborator {
  string String Id { get; set; }

  [HasOne("item", Link.None)]
  Item Item { get; set; }

  [ForeignKey("Item")]
  [Column("Item")]
  string ItemId { get; set; }
  
  [HasOne("user", Link.None)]
  User User { get; set; }
  
  [ForeignKey("User")]
  [Column("User")]
  string UserId { get; set; }
}

I would like the result (when ?includes=collaborators) to omit an array of ItemCollaborator and instead output an array of User. This is on par with the idea of aliases in the JSONAPI spec as mentioned in this ticket's description. The result, with this in mind, would be this:

{
"relationships": {
  "collaborators": {
    "data": [
      {
        "type": "users",
        "id": "user-b607e7dc-3a9d-4360-8495-dd37c4c99de8"
      }
    ]
  }
}

This allows the abstraction of a joining table to remain "database only" when dealing with simple one-to-many relationships where the joining entity includes nothing more than the related entity Ids.


Initial solutions to this requirement (via gitter discussions with @jaredcnance) landed on creating a modified version of the default IQueryable.Include(string) member in DefaultEntityRepository and adding support for something like [HasManyThrough("tags", nameof(ArticleTag), nameof(ArticleTag.Tags))] to attribute up entity members to infer types. The modified version would also need to consider pruning result data when it is not required (e.g. the joining table data).

This approach should fall in line with the intention to use reflection when building the ContextGraph so the PropertyInfo is readily available wherever it is needed.

@jaredcnance jaredcnance added this to the v2.2 milestone Jan 5, 2018
@bravo-kernel
Copy link

To add end-user context to the demand... from an end-user perspective this feature is highly desired as nested inclusions are about the only way to retrieve "very common" rich information without making multiple requests to the API.

I'm using Ember Data myself which, without this feature, requires hacking around the limitation.

@jaredcnance jaredcnance modified the milestones: v2.2, v3.0 Apr 8, 2018
@NullVoxPopuli
Copy link
Contributor

NullVoxPopuli commented Jul 2, 2018

I'd say this is an essential feature of jsonapi and is one of the biggest things that allows jsonapi to "compete" with features of graphql / custom-solutions.

nested includes is a must have for any generic jsonapi implementation (unless you're netflix, apparently)

@NullVoxPopuli
Copy link
Contributor

Is there enough demand?

imo, this is a pretty easy feature to maintain, because as you traverse the object graph, you just check if the object you are about to serialize has already been serialized in the included array. :-\

@jaredcnance
Copy link
Contributor Author

There is definitely enough demand and motivation to begin work on this feature. Unless someone else gets to it first, I will likely begin working on it after some in-flight work is completed (#326, #340, #344). If someone else wants to begin work on this, feel free to ping me on the Gitter channel and I'll be available to answer any questions.

milosloub pushed a commit to milosloub/JsonApiDotNetCore that referenced this issue Sep 24, 2018
milosloub pushed a commit to milosloub/JsonApiDotNetCore that referenced this issue Sep 24, 2018
…n-api-dotnet#39-implementation-deserializer-unit-test

Feature/json-api-dotnet#39 deserializer unit test
milosloub pushed a commit to milosloub/JsonApiDotNetCore that referenced this issue Sep 24, 2018
milosloub pushed a commit to milosloub/JsonApiDotNetCore that referenced this issue Sep 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants