1

I am using AWS AppSync for a chat app in one of the my applications. We are able to do setup and basic query successfully.

In one of the case I need to write a customized GraphQL query so that I can have additional data using reference of one type from another. For example, I can have allMessageGroup from a user and also allMessages from a particular group.

Now I want to add the last message in the group and its sender with the list of all message group just like what's app home page.

But I am not able to understand how make JOIN or write such query which give mixed results based on Conversation/Message/User types/table.

Platform:iOS Language: Swift

For detail below is my Schema and API/Query I am using

Schema

type Conversation {
  conversation_cover_pic: String
  conversation_type: String!
  createdAt: String
  id: ID!
  messages(after: String, first: Int): MessageConnection
  name: String!
  privacy: String
}
type Message {
  author: User
  content: String!
  conversationId: ID!
  createdAt: String
  id: ID!
  recipient: User
  sender: String
}
type MessageConnection {
  messages: [Message]
  nextToken: String
}

Query

query getUserConversationConnectionThroughUser($after: String, $first: Int)
{
    me
    {
        id
        __typename
        conversations(first: $first, after: $after)
        {
            __typename
            nextToken
            userConversations
            {
                __typename
                userId
                conversationId
                associated
                {
                    __typename
                    userId
                }
                conversation
                {
                    __typename
                    id
                    name
                    privacy
                    messages
                    {
                        __typename
                        id
                        conversationId
                        content
                        createdAt
                        sender
                        isSent
                    }
                }
            }
        }
    }
}
David Maze
  • 130,717
  • 29
  • 175
  • 215
Tarun Seera
  • 4,212
  • 4
  • 27
  • 41
  • I want to help but this is pretty close to unintelligible. Are you saying you want to return more than just `me` from your query? JOINS are not handled by GraphQL this can be handled by the resolvers. – None of your Beez Wax Jan 02 '19 at 20:18
  • I want to get result more than me, it can be based on conditional for example get the list of all chat groups also add last message in the group with group details which is available under conversation/group all message list – Tarun Seera Jan 03 '19 at 13:57
  • Can you show your resolvers? Graphql is just a way of defining boundaries and types. It does not say how to query or store the data. – None of your Beez Wax Jan 03 '19 at 14:05
  • Have you figured this out? I am facing the same issue, I can retrieve the object `me` in the iOS query and then all of the userConversations, but I am unable to go through the userConversations to find all the actual conversations. – Munib Jan 07 '19 at 23:14

1 Answers1

0

It sounds like you need multiple requests to one or more datasources to fulfill this graphQL query. In this case, you can use AppSync's pipeline resolver feature.

With pipeline resolvers, 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.

An example of something you could do with a pipeline resolver:

  1. One function will query the chat group database
  2. A second function will use the results of the chat group to fetch messages
  3. Consolidate all the results into one graphQL response containing group information and messages

Here is the documentation for pipeline resolvers: https://docs.aws.amazon.com/appsync/latest/devguide/pipeline-resolvers.html

  • There is no need to use pipeline resolvers, this query is used as an example in the appsync chat application which doesn't use pipeline resolvers as well. [Example](https://github.com/aws-samples/aws-mobile-appsync-chat-starter-angular/blob/master/src/app/chat-app/graphql/queries/getUserConversationsConnection.ts) – Munib Jan 07 '19 at 23:12
  • 1
    The other way to query multiple datasources would be to setup nested resolvers. This is the method used by the chat application. – Michael Willingham Jan 09 '19 at 00:04
  • Thanks for the reply. That makes sense, if I were to replicate the same query from the chat application in swift, how could that be done? This is the issue I am facing, [here](https://github.com/awslabs/aws-mobile-appsync-sdk-ios/issues/146). – Munib Jan 09 '19 at 06:52
  • 1
    You add 1) a resolver on the query itself, 2) a resolver on sub-fields of the query's return type. In your example, there is a resolver on the "me" query. "me" query returns a "User" type, and there are multiple resolvers on fields of the "User" type. Therefore, when you run the "me" query, the "me" resolver will run first, and then the "User.conversations" resolver will run second, with input from the "me" resolver. Here are the resolvers used in that example: [Resolvers](https://github.com/aws-samples/aws-mobile-appsync-chat-starter-angular/tree/master/backend/resolvers) – Michael Willingham Jan 09 '19 at 22:24
  • I completely understand, but when I generate the code using amplify for swift, it somehow doesn't generate the fields for `associated: [UserConversations]`. So even though my resolvers are setup exactly like the chat application, on the type `UserConversations` there isn't a subfield to be accessed in the first place. [Here](https://gist.github.com/returnzer0/5730b4fdcb9d5dbc14a68ead78fca2a2) is the codegen for swift that I am referring to. As you can see there is no way to reach associated from Me throgh UserConversations. – Munib Jan 10 '19 at 01:34
  • I have setup resolvers on `UserConversations` but I am unable to reach them in the swift code. That's the problem. – Munib Jan 12 '19 at 21:01