簡単にRESTサーバ・GraphQLサーバを立ち上げる


前回の投稿 JavascriptのImportとVueのコンポーネントを使えるようになってみる に引き続き、テンプレート環境の使い方をまとめておきます。
今回はサーバ側ということで、RESTサーバとGraphQLサーバの立ち上げ方を備忘録としてまとめておきます。

テンプレートは以下のGitHubに上げてあります。

poruruba/express_template
https://github.com/poruruba/express_template

※たびたび機能追加しているので、ここに記載していない機能も入っている可能性大です。

RESTサーバを立ち上げる

api/controllers/の配下に、適当なフォルダを作成し、index.jsとswagger.yamlを作成します。

index.jsは通常は、API Gateway経由でLambdaに転送されたときに似せています。

(i) JSON/POST呼び出しの場合

受け付けた呼び出しは、index.jsのexports.handlerで受け取ることができます。BODYに指定された引数を取得するには、以下のようにします。

exports.handler = async (event, context, callback) => {
    var body = JSON.parse(event.body);

(ii) GET呼び出しの場合

同様に、受け付けた呼び出しは、index.jsのexports.handlerで受け取ることができます。QueryStringの引数を取得するには、以下のようにします。

exports.handler = async (event, context, callback) => {
    var params = event.queryStringParameters;

レスポンスは、application/jsonで返すことが多いので、ヘルパー関数を用意しています。
こんな感じで返します。

    return new Response({ message: 'Hello World' });

もし、バイナリで返す場合は以下のようにします。

    return new BinResponse("application/octet-stream", buffer);

もし、テキストで返す場合は以下のようにします。

    return new TextResponse("text/html", str);

リダイレクトさせたい場合には、以下のようにします。

    return new Redirect(url);

swagger.yamlには、エンドポイントを定義します。Swagger2.0の定義のうちの、pathsとdefinitionsを定義します。(ただし、実際に参照しているのは、エンドポイント名だけですが。。。)
api/controllers/フォルダ配下にサンプルを置いていますので参考にしてください。

いくつかオプション設定できるようにしました。

〇オプションタグ: x-handler

 x-handler: 任意

通常は、エンドポイントが呼ばれると、index.jsのexports.handlerが呼び出されますが、このhandlerじゃない関数名で呼ばれたい場合にはここで指定します。
認証の検証をするわけではないのですが、パースして、index.js に結果を渡してあげます。

〇オプションタグ: security

security:
- basicAuth: []
- tokenAuth: []
- apikeyAuth: []
- jwtAuth: []

basicAuth : クライアントIDとクライアントシークレットがBase64でエンコードされた認証情報です。
 Authorization: basic [Bases64Encode(‘client_id’:’client_secret’)]

tokenAuth:OpenID ConnectやOAuth2のトークンを指定する場合の認証情報です。
 Authorization: bearer [Token]

apikeyAuth:APIキーを使った認証情報です。
 X-API-KEY:[APIKey]

jwtAuth:GCPのCloud Endpoint認証のための認証情報です。
 Authorization: bearer [Token]

Authorizationヘッダが設定されて呼び出される場合に指定します。req.requestContext に解析結果が設定されます。

〇オプションタグ: x-functype

x-functype: (express|empty|normal|alexa|lambda)

index.jsの呼び出し型を指定します。通常はnormalで、API Gateway経由でlambdaが呼ばれたときと同じようにふるまいますが、型を変えたい場合に指定します。

一応、忘れないように。Multipartでファイルを送るときは以下の指定にします。

〇file(multipart/form-data)の処理

parameters:
- in: formData
  type: file
  name: 任意

event.files.upfile[0] に受信したバイナリが格納されます。

npm run startで起動させると、api/controllers/配下の各フォルダにあるswagger.yamlを検索し、自動的にエンドポイントの定義を読み出して、エンドポイントを立ち上げるようにしています。

また、https://localhost:10080/swagger にアクセスすると、Yaml形式のSwagger定義をテキストで取得できます。
なので、以下のようなSwaggerエディタから、エンドポイントを可視化したり試しに呼び出しができます。

Swagger-Editor
 https://editor.swagger.io/

swagger-api/swagger-editor
 https://github.com/swagger-api/swagger-editor

File ⇒ Import URL で表示されるダイアログボックスに、立ち上げた上記のURLを入力してみてください。

npm run swaggerを実行することでも、各フォルダのswagger.yamlを結合してapi/swagger/swagger.yaml というファイルを出力することもできます。

GraphQLサーバの立ち上げ

api/controllers/の配下に、適当なフォルダを作成し、index.jsとschema.graphqlを作成します。

index.jsは以下のような感じで引数を取得し、schema.graphqlで定義したレスポンスに従って返すように実装します。

以下例です。

exports.handler = async(parent, args, context, info) =>{
    console.log("args", JSON.stringify(args));
    console.log("path", info.path);

    return "Hello World";
};

schema.graphqlは、もちろんGraphQLです。
※Subscriptionはまだ実装していませんので、書いても動きません。。。

例えばこんな感じです。

type Query {
  hello(message: String, param: Int): String
}

アノテーションでオプションを定義できるようにしています。

@endpointアノテーション

schema @endpoint(endpoint: "/mygraphql"){
  query: Query,
}

上記のアノテーションを記載しておくと、指定されたエンドポイント名でGraphQLのエンドポイントを立ち上げます。
上記の例では、エンドポイントは以下のようになります。

 http://localhost:10080/mygraphql

上記のアノテーションがない場合には、エンドポイントは自動的に以下のように割り当たります。

 http://localhost:10080/【フォルダ名】

@handlerアノテーション

type Query @handler(handler: "fulfillment", type: "lambda"){
  hello(param1: String, param2: Int): MyModelType
  test: [ToDo]
}

通常は、index.jsの呼び出しは、express_graphqlの呼び出し形式ですが、type:lambdaとすると、AWSのAppSyncに似せることができます。

handlerの定義は、通常は、index.js のexports.handerが呼び出されますが、名前を変えたい場合に指定します。handler: fulfillmentとした場合には、以下の部分が呼び出されます。

exports.fulfillment = async(parent, args, context, info) =>{

また、GraphQLエクスプローラも立ち上がるようにしています。
http://localhost:10080/graphql をブラウザで開くと以下のようなページが表示されます。
自動で立ち上げたGraphQLのフォルダ名が表示されています。

いずれかを選択すると、以下のようなGraphQLエクスプローラが立ち上がり、GraphQLのQueryやMutationの定義を確認したり、実際に実行を試すことができます。

ヘルパー

Alexaスキル、Alexaスマートホーム、Clova、LINEボット、Slack、Dialogflowなどとつなぐのに便利なヘルパをapi/helpers/に用意しています。

今後加筆するかもしれませんが、とりあえず以下を参考にしてください。ベースがテンプレート環境ではなくSwagger-Node環境で異なるのですが、ヘルパの使い方は同じです。

 SwaggerでLambdaのデバッグ環境を作る(1)

終わりに

こちらもご参考にどうぞ
 JavascriptのImportとVueのコンポーネントを使えるようになってみる

以上