Skip to content

Data Modeling II - Relations

We already created a One-to-many relationship between the Blog_Article and the category. This allows us to load the category along with the article, for example:

{
  Blog_listArticle {
    edges {
      node {
        title
        category {
          # Select categorie fields here:
          name
        }
      }
    }
  }
}

But to build a category page, we need the relation in the other direction: We need to be able to load the category with all its articles.

Instructions

To create relations between types, Slicknode provides the @relation directive.

One-to-many relation

Let's add an articles field to our Blog_Category that returns all articles of that particular category:

modules/blog/schema.graphql:

type Blog_Category implements Node {
  # ... the other fields
  articles: [Blog_Article!]!
    @relation(path: "Blog_Category=category.Blog_Article")
}

Deploy the changes and fix any potential error messages:

slicknode deploy

Now you can query the categories with all its articles. Open the Slicknode playground (slicknode playground) and test the relation with a GraphQL query, for example:

{
  Blog_listCategory {
    edges {
      node {
        id
        name
        articles {
          edges {
            node {
              id
              title
              text
              createdAt
            }
          }
        }
      }
    }
  }
}

Type Extensions

To create our author page, we need to do the same for the User type. The User type is part of a builtin Slicknode module, therefore we cannot add the field directly to the schema file where the User type is defined.

Slicknode allows you to extend types that are part of other modules. That way we can just add blog related fields for the User type in the same schema file where we define the other blog types. We just need to extend the type with the extend keyword. Note that we have to prepend the namespace of the module to the field name (Blog_) to avoid name collisions.

Add the following to the schema file of the blog module.

modules/blog/schema.graphql:

extend type User {
  Blog_articles: [Blog_Article!]! @relation(path: "User=author.Blog_Article")
}

Deploy the changes again and fix any error messages:

slicknode deploy

Now test the relationship in the playground slicknode playground, for example to load all articles of the currently logged in user:

{
  viewer {
    user {
      email
      firstName
      lastName
      Blog_articles {
        edges {
          node {
            id
            title
            text
          }
        }
      }
    }
  }
}

Explanations

The Slicknode @relation directive is a flexible directive that allows you to add relationship fields to types in your schema in a flexible way. Slicknode uses the type information to automatically add all the data fetching logic, filter types, sorting, pagination, etc.

Any field that is added with a @relation directive does not change the underlying data that is stored or the database tables, it just provides Slicknode with the information it needs to generate the field resolvers.

To learn in depth how the @relation directive works, check out the relations documentation