reym
CRUD/Schema/Object

@filterByJwtData

A JWT can contain a field called data. This field can contain a key-value object. The @filterByJwtData directive uses this object to do automatic filtering on CRUD entries. The APIs will only return entries where the value of the field matches the value of the JWT data object field.

The JWT data object field is identified by the jwtDataKey argument of the directive. The path to the value in the JWT data object is identified by the path argument of the directive. Both arguments are required.

JWT (JSON Web Token)

JSON Web Tokens are an open, industry standard method for representing claims securely between two parties. In the context of Freym, JWTs are used to pass data to the service.

Validation

Since this directive is used to filter data, it is validated every time it is declared.

The validation checks the following conditions on the field that the directive is applied to:

  • the jwtDataKey argument is given
  • the field is a scalar

Definition Scalar

A scalar is a key that resolves to a concrete value. Find more information in the GraphQL Documentation.

Example Setting

The following example shows how to use the @filterByJwtData directive to filter data based on a JWT. In our example, we have an Concert object with several nested objects in its hierarchy. These objects are structured as follows:

  • Every Order belongs to exactly one Concert.
  • Every OrderTicket belongs to exactly one Order.

Hence, the Concert is the parent of the Order and the Order is the parent of the OrderTicket.

This illustration shows the data structure, with each circle representing an object or a field:

Our business objective is to sell concert tickets via an e-commerce application. Therefore, we need to provide certain parts of the data structure to the frontend of our application.

Example with Returned Child Values

Let's say we want to design an overview page of all orders for a specific concert. For a CRUD type, we would then choose the following approach:

concert.graphql
type Concert @crudType @filterByJwtData(jwtDataKey: "concert", path: "id") {
    name: String!
    order: Order
}

This JWT:

jwt.json
{
    // ...
    "data": {
        "concert": "concert-id"
    }
    // ...
}

will return orders belonging to the concert object with the ID "concert-id".

Below you find a graphical representation of the data structure with the returned objects marked in blue:

As you can see, the order object is returned, which is a child of the concert object.

Example with Returned Parent Value

Next up, we want to display a page with all the important information for a specific concert. This implies that our CRUD type must return the concert object itself, which looks like this:

order.graphql
type Order @crudType @filterByJwtData(jwtDataKey: "concert", path: "concert.id") {
    concert: Concert!
}

This JWT:

jwt.json
{
    // ...
    "data": {
        "concert": "concert-id"
    }
    // ...
}

will return concert objects where the id field of the concert object equals the value "concert-id".

Below you find a graphical representation of the data structure with the returned objects marked in blue:

As you can see, the concert object is returned, which is the parent of the order object. In the scope of this example, the complete object is returned, but you can also return only specific fields.

Example with Nested Path Resolution

Let's say we need an edit page to change the details of a ticket for a specific concert, belonging to a specific order. The CRUD type is a bit more complex, as it needs to resolve the nested path of the concert and order object:

orderticket.graphql
type OrderTicket @crudType @filterByJwtData(jwtDataKey: "concert", path: "order.concert.id") {
    order: Order @filterByJwtData(jwtDataKey: "concert", path: "concert.id")
}

This JWT:

jwt.json
{
    // ...
    "data": {
        "concert": "concert-id"
    }
    // ...
}

will return an OrderTicket object belonging to the order field defined in the CRUD type. This order field in turn looks for orders belonging to an concert with the ID "concert-id".

In the graphical representation below, you can see the returned objects marked in blue and their parent object marked in orange:

As you can see, the orderticket objects within a certain order object are returned.

Array JWT payload

You can also filter for arrays in the JWT payload.

orderticket.graphql
type OrderTicket @crudType @filterByJwtData(jwtDataKey: "concert", path: "order.concert.id") {
    order: Order
}

This JWT:

jwt.json
{
    // ...
    "data": {
        "concert": ["concert-id", "concert-id-2"]
    }
    // ...
}

will return an OrderTicket object belonging to the order field defined in the crud type. This order field in turn looks for orders belonging to an concert with the IDs "concert-id" or "concert-id-2".