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には、引数に対応したコードの生成機能は無く未対応だと書いてあった。
上記の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); } });
実際のリポジトリ