Modeling Relationships - Join Table - GraphQL - AWS Amplify - AppSync - React
Tags: tutorial, aws, react, graphql
Published: 2020-05-11 23:00:59

### **Goal**

Join 2 tables in a GraphQL schema.

If you are using AWS Amplify and AppSync with a GraphQL API and have experienced some difficulty with modeling your relationships, this is a very simple method to connect your tables.

### **Creating the GraphQL API**

Use this simple command: 

```
amplify add api
```

For more detailed steps with creating your GraphQL API, check out the [AWS Amplify docs](https://docs.amplify.aws/lib/graphqlapi/getting-started/q/platform/js).

### **Tables**

First, let's create our the two tables we'd like to join:

**Playlist:**
```graphql
type Playlist @model {
  id: ID!
  name: String!
  description: String!
  owner: String
  createdAt: String
}
```

**Post:**
```graphql
type Post @model {
  id: ID!
  name: String!
  description: String!
  thumbnail: S3Object!
  video: S3Object!
  owner: String
  createdAt: String
}
```

### **Relationships**

A **Playlist** has many **posts**.
A **Post** can belong to many **playlists**.

We must create *two* **1:Many** relationships which will help us achieve the **Many:Many** relationship we need to join **playlists** and **posts**.

Let's now create the necessary 1:Many relationships with connections in each table:

**Playlist:**
```graphql
type Playlist @model {
  id: ID!
  name: String!
  description: String!
  owner: String
  createdAt: String
  posts: [PlaylistPost] @connection(name: "PlaylistPost")
}
```

**Post:**
```graphql
type Post @model {
  id: ID!
  name: String!
  description: String!
  thumbnail: S3Object!
  video: S3Object!
  owner: String
  createdAt: String
  playlists: [PlaylistPost] @connection(name: "PostPlaylist")
}
```

### **The Join Table**

We can reference these connections with a *third* table (remember to reference these connections with the same name):

```graphql
type PlaylistPost @model {
  id: ID!
  createdAt: String
  playlist: Playlist @connection(name: "PlaylistPost")
  post: Post @connection(name: "PostPlaylist", sortField: "updatedAt")
}
```

Deploy your API (this could take a few minutes):

```
amplify push
```

### **Configure Your Application**

Install the required AWS Amplify package.

```
npm install aws-amplify
```

Import your AWS Amplify files in **App.js**:

```javascript
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
```

Now we have access to all GraphQL query, mutation and subscription operations. 

### **Adding a Post to a Playlist**

Now that we have our two tables joined by the **PlaylistPost** table, we can add a **post** to a **playlist** by simple creating a *new* PlaylistPost.

AWS Amplify has built-in API and GraphQL functions you can use by importing them from aws-amplify. I *highly* recommend reading the [AWS Amplify docs](https://docs.amplify.aws/lib/graphqlapi/mutate-data/q/platform/js).

```javascript
import { API, graphqlOperation } from 'aws-amplify'
import { createPlaylistPost } from '../graphql/mutations'
```

```javascript
const add = async (playlist, post) => {
  try {
     // Specify the id of the post
     // and the playlist you want to add that post to
      const newPlaylistPostInput = {
          playlistPostsPlaylistId: playlist.id,
          playlistPostsPostId: post.id
      }
      const updatedPost = await API.graphql(graphqlOperation(createPlaylistPost, { newPlaylistPostInput }))

  } catch(err) {
      console.log(err)
  }
}
```

### **Removing a Post from a Playlist:**

```javascript
import { API, graphqlOperation } from 'aws-amplify'
import { deletePlaylistPost } from '../graphql/mutations'
```

```javascript
const remove = async (selectedItem) => {
  try {
     // Specify the id of the PlaylistPost you want to delete
      const input = {
                id: selectedItem.id,
            }
            const removed = await API.graphql(graphqlOperation(deletePlaylistPost, { input }))
      }
  } catch(err) {
      console.log(err)
  }
}
```

### **You Did It!**

You have successfully created a join table in your GraphQL schema as well as used AWS Amplify GraphQL operations to connect a **post** to a **playlist**. Now you can use these same steps to join other tables with similar relationships.

*Note: For more guidance, I definitely suggest (for the 4th time) to read through the [AWS Amplify documentation](https://docs.amplify.aws/lib/graphqlapi/getting-started/q/platform/js).*