0

I have a JSON API endpoint for retrieving the user. This resource will also be used to get the permissions of the user, for showing or hiding specific elements in our front end application.

The resource looks like this:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "jsonapi": {
    "version": "1.0"
  },
  "meta": {
    "content-type": "application/vnd.api+json"
  },
  "links": {
    "self": "/users/some-uuid"
  },
  "data": {
    "type": "users",
    "id": "some-uuid",
    "attributes": {
      "email": "some-email@example.com",
      "permissions": [
        "view-all-users",
        "view-all-shifts"
      ]
    },
    "relationships": {
      "roles": {
        "data": [
          {
            "type": "role",
            "id": "some-role-uuid"
          }
        ]
      }
    }
  }
}

The permissions attribute holds the slugs for the permissions that the user has.

If this attribute was not present the front end application would have to include the resources roles and roles.permissions to be able to get to the user's permissions. That response would look like the following:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "jsonapi": {
    "version": "1.0"
  },
  "meta": {
    "content-type": "application/vnd.api+json"
  },
  "links": {
    "self": "/users/some-uuid"
  },
  "data": {
    "type": "users",
    "id": "some-uuid",
    "attributes": {
      "email": "some-email@example.com",
      "permissions": [
        "view-all-posts",
        "edit-all-posts"
      ]
    },
    "relationships": {
      "roles": {
        "data": [
          {
            "type": "role",
            "id": "some-role-uuid"
          }
        ]
      }
    },
    "included": [
      {
        "type": "roles",
        "id": "some-role-uuid",
        "attributes": {
          "name": "Editor"
        },
        "relationships": {
          "permissions": {
            "data": [
              {
                "type": "permission",
                "id": "some-permission-uuid"
              },
              {
                "type": "permission",
                "id": "some-permission-uuid-2"
              }
            ]
          }
        }
      },
      {
        "type": "permissions",
        "id": "some-permission-uuid",
        "attributes": {
          "slug": "view-all-posts"
        }
      },
      {
        "type": "permissions",
        "id": "some-permission-uuid",
        "attributes": {
          "slug": "edit-all-posts"
        }
      }
    ]
  }
}

In this case the front end has to do a lot of processing just to get to the permission slugs. My question here is: Is it bad to have a short hand attribute permissions on the user resource like the above example, or should the front end always get to the slugs through the relationships?

Note: In the future we will have an admin interface where the user can manage users, roles and permissions. That is why the roles and permissions are available as seperate entities.

  • 1
    How would the front end know in that case that an update to a `role` might changes the `permission` attribute of the user? I'm also not quite sure what you mean by a "log of processing". I would expect that a client of JSON:API uses an implementation that provides a nice interface to access related records. I don't think there is a performance difference relevant for any real world usage example. Response body size is a little bit higher for a single resource but that shouldn't be relevant after gzip and may even be less for collections. – jelhan Mar 07 '19 at 23:46

1 Answers1

0

Client apps can easily merge all the permissions from roles into one key/array themselves and work from there. This way you'll keep the principles of JSON API in tact and give the client apps the freedom to work with permissions as they prefer.

  • 1
    You might want to rephrase or answer more precisely with a solution to this very problem. You're stating that this is easily solvable without posting a proper example or solution. – bastianwegge Mar 11 '19 at 08:46