見出し画像

ローコードでオリジナルのAPIを作る3つの方法まとめ

2024/8/25 Lambdaで使用するnode.jsのバージョンを最新の「20.x」にしました。

下記の2記事の続きです。
これまで、プログラミングを始めたい人が、開発環境を準備して、自分のWebサービスをインターネットに公開して、ChatGPTのAPIをつかってオリジナルのChatGPTクライアントを実装するところまでを解説してきました。

ここまでの技術があれば、既存のAPIを組み合わせて、アイデア次第でかなりいろいろなWebサービスを開発できると思います。
今回は、さらにもう一歩ステップアップして、オリジナルのAPIを開発する方法を紹介します。この技術を身につければ、拡張性とかセキュリティとかはともかく、思いついたアイデアはなんでも実装できるようになるはずです。

【初級】Zapierでつくる

Zapierとは

一番簡単なAPI開発手法として紹介したいのは、データ連携ツールのZapier(ザピアー)です。クラウドサービス間のデータ連携を自動化できるツールで、ノーコード界隈では有名なので、使っている方もいらっしゃるかもしれません。
例えば僕は「HubSpotの問い合わせフォームに入ってきた情報をSalesforceに転送する」という処理をZapierで作っています。

弊社の問い合わせフォームはHubSpotで作っていますが、問い合わせ内容はSalesforceに転送して処理しているのです。

さて、残念ながら有料プラン限定にはなってしまうのですが、実はZapierには、作ったフロー(Zap)をAPI化する機能があり、それがとても便利です。

ZapierでAPIをつくる

新しいZapをつくり、トリガーとして「Webhook」を選択してください。

残念ながらPremium限定…!

イベントは「Catch Hook」を選択して「Continue」。

「Trigger」を指定すると受け取るパラメーターを限定できるのですが、とりあえず無視して「Continue」。

すると、APIのURLが出てきます。このURLをたたくと、いま編集しているフローが動くということです。コピーしましょう。

ここでAPIに送り込みたいパラメータを定義します。例えば、コピーしたURLに、「?a=10&b=test」と付与してたたいてみました。すると、「このAPIにはa, bという2つのパラメーターを送るよ」という合図になります。値はサンプル値を適当に考えて設定します。

Zapierから応答が帰ってきますね。

その後、Zapierの画面に戻って「Test Trigger」を押すと、いま設定したパラメータがZapierで認識されています。

あとは、Zapierを使ったことがある方はなんとなくわかるはずです。このAPIがたたかれることをトリガーとして、いろんな処理を動かすことができます。
例えばこれは、「受け取った値をGoogleスプレッドシートに記録するAPI」です。

このように、ノーコードで簡単にAPIを自作できます。
Zapierの弱点は、条件分岐を作りにくいところです。ですから、複雑な処理を実装するというよりは、Reactで作ったシステムからスプレッドシートなどデータベースとなるツールにデータを送り込んだり、他のシステムを起動したりするAPIとして有効に使えます。


【中級】Google Apps Script(GAS)でつくる

GASとは

2つ目の方法は、Googleドライブの拡張機能として使えるGoogle Apps Script(GAS)です。特に、GoogleスプレッドシートをDBとして、そこにデータを書き込んだり、データを読み出したりするAPIを実装するのが便利です。

GASでAPIをつくる

新しいスプレッドシートを開いて、拡張機能>Apps Scriptを選びましょう。

これがGASの開発画面です。

API開発するためには、GET用とPOST用のテンプレートプログラムを持っておいて、これをコピペして使います。

//GETされたときに呼ばれる処理
function doGet(e) {
  //パラメータ「p」の値を取得
  var param = e.parameter.p;

  //スプレッドシートと連携する処理を書く

  //APIの応答を返却
  return ContentService.createTextOutput("{body:" + param + "}");
}
//POTされたときに呼ばれる処理
function doPost(e) {
  //パラメータ「p」の値を取得
  var param = e.parameter.p;

  //スプレッドシートと連携する処理を書く

  //APIの応答を返却
  return ContentService.createTextOutput("{body:" + param + "}");
}

「doGet」と「doPost」が違うだけですね。呼び出し側の要件に応じて使い分けます。

プログラムが書けたら、右上の「デプロイ」から「新しいデプロイ」を選択します。

  • 種類の選択:ウェブアプリ

  • 名前:適当につける

  • アクセスできるユーザー:全員

と指定してデプロイします。

デプロイが完了すると、APIのURLが出てきます。このURLをたたくと、doGetやdoPostが起動する、ということですね。

試してみましょう。出てきたURLの後ろに「?p=testmessage」を付与して叩きます。doGetのプログラムが動作していることがわかりますね。

【上級】AWS Lambdaでつくる

Lambdaとは

たいていの処理はGASでも実装できるのですが、処理が遅いとか、ログが出ないので運用が大変とか、細かい問題がいろいろあります。将来的に拡大していく計画があるAPIの場合は、もう少し運用しやすい形態で開発したいものです。

そこでおすすめなのが、AWSのローコードツール「Lambda(ラムダ)」です。PythonやJavaScriptで書いたプログラムをAPI化することができます。

LambdaでAPIをつくる

AWSにログインしたら、検索ウインドウから「Lambda」を検索します。
Lambdaの画面で、「関数の作成」ボタンを押しましょう。

関数の新規作成画面では、以下の部分を設定します。

  • 関数名:自由に名前をつけます

  • ランタイム:「Node.js 20.x」を選びます。

  • 実行ロール:「AWSポリシーテンプレートから新しいロールを作成」→ポリシーテンプレートとして「DynamoDB」を選択します。ロール名は自由に設定します。ここでLambda以外のサービスとの接続設定を行っています。

  • 関数URLを有効化:ONにします。自動的にAPIとしての呼び出しURLが発行されます。

  • 認証タイプ:今回はNONEに設定します。個人情報など重要な情報をあつかうときは、設定した方が良いです。

  • オリジン間リソース共有(CORS)を設定:ONにします。これをONに設定しないと、Reactのプログラムから呼び出したときにエラーが発生します。

デフォルトで、「Hello from Lambda!」と返却するAPIのプログラムが書かれています。

設定>関数URLを開くと、このプログラムをAPIとして呼び出すURLが書かれています。

ブラウザで関数URLをたたくと、確かに「Hello from Lambda!」と返ってきます。

あとはプログラムを自由に書き換えるだけです。
パラメーターの受け取り方が重要ですね。

//GETパラメータを受け取る。event['queryStringParameters']['パラメータ名']
export const handler = async (event) => {
  // TODO implement
  const response = {
    statusCode: 200,
    body: JSON.stringify('parameter is ' + event['queryStringParameters']['p']),
  };
  return response;
};
//POSTパラメータを受け取る。
export const handler = async (event) => {
  //まずは要求のJSONを取り出す
  const eventbody = JSON.parse(event['body']);

  //JSONからパラメータの値を取り出す
  const response = {
    statusCode: 200,
    body: JSON.stringify('parameter is ' + eventbody['p']),
  };
  return response;
};


DyanamoDBとLambdaを接続する

AWSにはDBのサービスが複数ありますが最も使いやすいのはDynamoDBです。使いやすいポイントとしては、GUIで項目を追加したり削除したりできることです。AWSの他のDBは、SQLを書かないと操作できません。

DynamoDBは、かなり直感的に操作できます。
新しいデータを管理したい場合には、左メニューから「テーブル」>「テーブルの作成」ボタンを押します。

パーティションキーは必須項目です。「ID」など、データの1つ1つで、必ず一意になる項目を用意しなければなりません。

テーブルを作成したら、左メニュー「項目を探索」で値の追加・更新・削除ができます。最終的には全部Lambdaから登録することになるはずですが、テスト用のデータなどを手投入して、いろいろ検証するのに便利ですね。

DynamoDBのテーブルが準備できたら、あとはLabmdaからDynamoDBにアクセスする処理を書きます。

検索する、更新する、新規登録、という基本的なDB操作処理をテンプレートプログラムとして使いまわすのが良いでしょう。
下記は、「engineers」というテーブルをAPIの要求パラメータとして受け取ったemailで検索し、既存レコードが見つかったらnameを更新、見つからなかったらレコードを新規登録する、というAPIです。

// LambdaとDynamoDBの接続設定
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, GetCommand, ScanCommand, PutCommand, UpdateCommand } from "@aws-sdk/lib-dynamodb";
const dynamoDbClient = DynamoDBDocumentClient.from(new DynamoDBClient({}));

// Lambdaハンドラ関数
export const handler = async (event) => {
    try {
        const paramEmail = JSON.parse(event.body).email;
        const paramName = JSON.parse(event.body).name;
        
        //検索する///////////////////////////////////////
        const getParams = {
            TableName: "engineers",  //検索するテーブル名
            Key: { 
                email: paramEmail    //検索条件
            }            
        };
        const data = await dynamoDbClient.send(new GetCommand(getParams));
        ///////////////////////////////////////////////

        if (data.Item) {
            // 既存のデータが見つかったら、名前を更新する

            //更新する///////////////////////////////////////
            let updateParams = {
                TableName: 'maiteUsers',
                Key: {
                    email: paramEmail,        //検索対象の検索条件
                },
                ExpressionAttributeNames: {
                    '#name': 'name',          //更新する項目名
                },
                ExpressionAttributeValues:{
                    ":name": paramName,       //更新する値
                },
                UpdateExpression: "set #name  = :paramName"  //更新条件の設定
            };
            await dynamoDbClient.send(new UpdateCommand(updateParams));
            ///////////////////////////////////////////////

            return {
                statusCode: 200,
                body: JSON.stringify(data.Item)
            };
        } else {
            // データが見つからない場合は新規作成

            //登録する///////////////////////////////////////
            const newItem = {
                "email": paramEmail,    //登録する値の設定
                "name": paramName,
            };
            await dynamoDbClient.send(new PutCommand({ TableName: "engineers", Item: newItem }));
            ///////////////////////////////////////////////

            return {
                statusCode: 200,
                body: JSON.stringify(newItem)
            };
        }
    } catch (error) {
        console.error(error);
        return {
            statusCode: 500,
            body: JSON.stringify('Error: Could not retrieve or create item')
        };
    }
};

DB操作のプログラムは、たいてい上記の形になると思うので、これをテンプレートとして使いまわすと便利です。
あとはテーブル名や条件の部分を書き換えれば、いろいろなDB操作ができます。特に難しいのは、更新の方法でしょうか。ちょっとクセのある文法で、慣れが必要です。

公式ドキュメントにも、検索、更新、追加それぞれの例が書かれているのでこちらも参考になります。

LambdaとDynamoの連携はZapierやGASと比較すると難易度が高いですが、1回動かせばコツがつかめると思いますし、何より開発の自由度がとても高くなることがメリットです。

まとめ

APIを自作できるようになると、開発の幅が大きく広がります。ローコードツールを駆使して、いろんなAPIを作ってみてください!


この記事が気に入ったらサポートをしてみませんか?