json-api-dotnet/JsonApiDotNetCore

Empty attributes returned on overridden relationship endpoint

Closed this issue · 2 comments

DESCRIPTION

I’m trying to customize the secondary endpoint
/profiles/{id}/groups.

In my data model, Profile has many Groups through a pivot table (ProfileGroup), and Template also has many Groups through another pivot table (TemplateGroup). Each Profile is linked to a single Template.

What I want is that when a client calls /profiles/{id}/groups, the response should contain all groups:
• groups directly linked to the profile, and
• groups linked through the template of that profile.

At the same time, I need to preserve the normal JSON:API behavior:
filters, sorting, pagination, sparse fieldsets (fields), and includes should all still work as if this were a regular HasMany relationship.

STEPS TO REPRODUCE

Features
  • Models:
    • Profile (linked to a single Template, many-to-many with Group via ProfileGroup)
    • Template (many-to-many with Group via TemplateGroup, one-to-many with Profile)
    • Group (many-to-many with both Profile and Template)
    • Pivot tables: ProfileGroup, TemplateGroup (with JSON Options field)
  • DbContext:
    • Configured for MySQL using Pomelo.EntityFrameworkCore.MySql
    • Relationships and navigation properties set up for EF Core
  • JsonApiDotNetCore:
    • Models annotated with [Resource] and inherit from Identifiable<int> for automatic JSON:API endpoints
    • Namespace /api for all resources
Usage
  • Start the API and access / to see all available routes.
  • JSON:API endpoints are available under /api/groups, /api/profiles, /api/templates, etc.
  • The database is seeded with example data on startup.
  • Browse the routes:
    • /api/profiles/1/groups
    • /api/profiles/2/groups

EXPECTED BEHAVIOR

Attributes must be filled

/api/profiles/1/groups

{
  "links": {
    ...
  },
  "data": [
    {
      "type": "groups",
      "id": "1",
      "attributes": {
        "name": "Group 1"
      },
      "relationships": {
        ...
      },
      "links": {
        ...
      }
    },
    {
      "type": "groups",
      "id": "2",
      "attributes": {
        "name": "Group 2"
      },
      "relationships": {
        ...
      },
      "links": {
        ...
      }
    }
  ]
}

/api/profiles/2/groups

{
  "links": {
    ...
  },
  "data": [
    {
      "type": "groups",
      "id": "2",
      "attributes": {
        "name": "Group 2"
      },
      "relationships": {
        ...
      },
      "links": {
        ...
      }
    }
  ]
}

ACTUAL BEHAVIOR

Attributes are empty

/api/profiles/1/groups

{
  "links": {
    ...
  },
  "data": [
    {
      "type": "groups",
      "id": "1",
      "attributes": {
        "name": null
      },
      "relationships": {
        ...
      },
      "links": {
        ...
      }
    },
    {
      "type": "groups",
      "id": "2",
      "attributes": {
        "name": null
      },
      "relationships": {
        ...
      },
      "links": {
        ...
      }
    }
  ]
}

/api/profiles/2/groups

{
  "links": {
    ...
  },
  "data": [
    {
      "type": "groups",
      "id": "2",
      "attributes": {
        "name": null
      },
      "relationships": {
        ...
      },
      "links": {
        ...
      }
    }
  ]
}

VERSIONS USED

  • JsonApiDotNetCore version: 5.8.1
  • ASP.NET Core version: 8.0
  • Entity Framework Core version: 9.0.8
  • Database provider: MySql

Test repository

https://github.com/alexeidick/json-api-dotnet-relationship-test

Thanks. Can you verify if alexeidick/json-api-dotnet-relationship-test#1 resolves the issue?

Hi,

Thank you :)

Replace

ResourceType groupType = _graph.GetResourceType<Group>();
QueryLayer secondaryLayer = _composer.ComposeSecondaryLayerForRelationship(groupType);

By

ResourceType groupType = _graph.GetResourceType<Group>();
QueryLayer secondaryLayer = _composer.ComposeFromConstraints(groupType);

Fixed my issue!