Amplify AppSync 自動生成したコードのsubscriptionで引数を利用する。

Amplify AppSync

amplify add apiを行った時に、クエリ・ミューテーション・サブスクリプション用のコードを自動生成するか聞かれます。これは、自動生成を行った場合に悩んだ箇所です。

生成もとのschemaが以下

type Subscription {
  onCreateMessage(roomId: ID!): Message
    @aws_subscribe(mutations: ["createMessage"])
}

そして生成されたsubscriptionがこれ。

見て分かる通り、graphql内でroomIdを使用しているが引数などを指定する箇所が無い。

  OnCreateMessageListener: Observable<
    OnCreateMessageSubscription
  > = API.graphql(
    graphqlOperation(
      `subscription OnCreateMessage($roomId: ID!) {
        onCreateMessage(roomId: $roomId) {
          __typename
          id
          content
          when
          roomId
          owner
          room {
            __typename
            id
            createdAt
            updatedAt
          }
        }
      }`
    )
  ) as Observable<OnCreateMessageSubscription>;

GitHubのIssueには、引数に対応したコードの生成機能は無く未対応だと書いてあった。

github.com

上記のIssue内にあった対処方法を利用することにした。

自動生成されたコードをいじりたくなかったので、生成されたクラスを拡張して新たにサブスクリプション用の関数を作ることにした。

import {OnCreateMessageSubscription, APIService} from "./API.service";
import API, {graphqlOperation} from "@aws-amplify/api";
import * as Observable from "zen-observable";
import {Injectable} from "@angular/core";

@Injectable({
  providedIn: "root"
})
export class MyAPIService extends APIService {
  constructor() {
    super();
  }

  MyOnCreateMessageListener(
    roomId: string
  ): Observable<OnCreateMessageSubscription> {
    const statement = `subscription OnCreateMessage($roomId: ID!) {
        onCreateMessage(roomId: $roomId) {
          __typename
          id
          content
          when
          roomId
          owner
          room {
            __typename
            id
            createdAt
            updatedAt
          }
        }
      }`;
    const gqlAPIServiceArguments: any = {
      roomId
    };
    return API.graphql(
      graphqlOperation(statement, gqlAPIServiceArguments)
    ) as Observable<OnCreateMessageSubscription>;
  }
}

使用例

import {MyAPIService} from "../API.my";
// Subscribe to creation of Message
const messageSubscription = this.api.MyOnCreateMessageListener(this.roomid);
messageSubscription.subscribe({
  next: newMessage => {
        this.messages.push(newMessage.value.data.onCreateMessage);
  }
});

実際のリポジトリ

github.com