rodrigo-silveira
rodrigo-silveira

Reputation: 13078

GraphQL field resolver needs contextual information

Maybe my terminology is not accurate. I'm using AWS AppSync. My schema:

type Book {
  title: String
  author: Author
}

type Author {
  name: String
}

type Query {
  getBook(title:String!): Book
}

The resolver for getBook returns an object shaped as:

{
  title: <string>
  authorId: <number>
}

Where authorId is always returned.

What I'd like to do is specify a resolver for the field Book.author that will receive authorId and fetch that object from its own data store. Is this possible?

If what I'm trying to do is not possible, what is the proper way of doing this, where one data store is a table with two columns - { title, authorId }, and a separate store has a table with a list of authors, where the primary key is a column authorId. Since these are two different services, I can't just join the two like a SQL query.

Upvotes: 0

Views: 426

Answers (2)

Tinou
Tinou

Reputation: 6158

As long as authorId is returned from the getBook resolver, it will be accessible via $ctx.source.authorId when resolving Book.author.

I reproduced your API with local resolvers using your schema:

Query.getBook request mapping template:

{
    "version": "2018-05-29",
    "payload": {
        "title": "$context.arguments.title",
        "authorId": "2" ## returned in addition to other fields. It will be used by Book.author resolver.
    }
}

Query.getBook response mapping template:

$util.toJson($context.result)

Book.author request mapping template:

{
    "version": "2018-05-29",
    "payload": {
        "name": "author name with authorId: $context.source.authorId"
    }
}

Book.author response mapping template:

$util.toJson($context.result)

The following query:

query {
  getBook(title:"AWS AppSync") {
    title 
    author {
      name
    }
  }
}

will yield the results:

{
  "data": {
    "getBook": {
      "title": "AWS AppSync",
      "author": {
        "name": "author name with authorId: 2"
      }
    }
  }
}

Upvotes: 1

KoingDev
KoingDev

Reputation: 620

You might need to have bookID as parent's ID inside Author:

type Author {
    # parent's id
    bookID: ID!
    # author id
    id: ID!
    name: String!
}

type Book {
    id: ID!
    title: String!
    author: Author!
}

When Create Resource, just make:
- Book.id as primary key of BookTable
- Author.bookID as primary key and Author.id as sort key of AuthorTable

enter image description here

You also need to attach resolver for Book.author using $ctx.source.id

enter image description here

After you attach Book.author resolver, you are good to go. You can get result something like below:

getBook(title: "xx") {
  id
  title
  author {
    id
    name
  }
}

Upvotes: 1

Related Questions