0

I'm experimenting with AppSync + DynamoDB. I want to have the following types in my GraphQL Schema:

type User {
    user_id: String!
}

type Box {
    name: String!
    user: User!

}

How can I create, in DynamoDB, a table storing items pointing to another table (In my case, I want the field user of the table BoxTable to be a reference to a user in the table UserTable?

How can I, in AppSync, define the above schema? When I set user: User!, I get the error Expected User! to be a GraphQL input type.?

Eric
  • 477
  • 3
  • 17

1 Answers1

1

As per my understanding of your question, these are my answers.

How can I create, in DynamoDB, a table storing items pointing to another table

DynamoDB is not a relational database and does not offer foreign keys or table joins. Therefore, to achieve what you have mentioned in your post, you would still require two calls to DynamoDB to get all the information for the Box i.e. first get the Box item from BoxTable and then get user from UserTable based on user_id. If your use case is such that you get user first, then you can get the Box using filter by user_id.

Now to the second part of your post,

How can I, in AppSync, define the above schema?

With DynamoDB unit resolvers, you can query against a single table (outside of DynamoDB Batch Operations but those are reserved for bulk use cases).

One way of doing this is by defining your schema that should look something like this;

type User {
    user_id: String!
}

type Box {
    name: String!
    user: User!
}

input BoxInput {
    name: String!
    user: UserInput!
}

input UserInput {
    user_id: String!
}

type Mutation {
    createBox(input: BoxInput): Box
}

type Query {
    getBox(input: BoxInput): Box
}

And this is how you can run query and mutation;

mutation createBox {
        createBox(input: {
            name: "abc"
            user: { user_id: "1234-abcd-5678-efgh"}
        }){
            name
            user { user_id }
        }
    }

query getBox {
        getBox(input: {
            name: "abc"
            user: { user_id: "1234-abcd-5678-efgh"}
        }){
            name
            user { user_id }
        }
    }

So, beware of the above query and mutation. These will show user as null unless you attach a separate resolver with you user type within your Box type. For example:

Query that returns Box --> Resolver

type Box {
    name
    user --> Attach resolver to get user_id from your UserTable
}

Other way is to utilize the pipeline resolvers in which you can create multiple functions, each of which can use the results of the previous function and query a database. These functions run in an order you specify. For example:

  1. Function to get Box from BoxTable.
  2. Function to get user from UserTable by using user_id from ctx.prev.result.
  3. And finally consolidating above two result into one JSON object depending upon Box type in your schema.
Myz
  • 818
  • 1
  • 8
  • 21