🍈

(ほぼ) パケ無しNode.jsでAPI

に公開

なんの記事?

ほぼ素のNode.jsでDBと疎通して、データをIOするシンプルなWebAPIを実装しました

  • 使ったライブラリ: pg (Postgresクライアント)
  • Expressなどは利用せず

APIの構成

  • ヘルスチェック + AWSのサービスをDBに登録、一覧、詳細API表示する
    • GET /health
    • GET /aws-services
    • GET /aws-service/{id}
    • POST /aws-service
  • やらないこと
    • 認証の実装
    • ORMの選定
    • 画面側の実装

ディレクトリ構成

  • 📁ROOT
    • 📝compose.yaml コンテナ定義。appフォルダをマウントする
    • 📁app
      • 📝package.json
      • 📝server.js HTTPサーバ本体
      • 📁api
        • 📝route.js パスで下位フォルダに振り分け
        • 📁health
          • 📝handler.js : HTTPメソッドなどで振り分けて、executerに投げる
          • 📝executer.js: 関連する処理を📁dbに投げる
        • 📁aws-service
          • 📝handler.js
          • 📝executer.js
      • 📁db
        • 📁aws-service: aws-serviceテーブルのDAO
        • 📁health: DAOはないが、healthチェックの一環でテスト接続する
        • 📝connection.js DBコネクションのハンドリング
        • 📝core.js SQL実行
      • 📁util 雑多な処理

工夫したところ

📁app/api配下

route.jsがトップレベルのパスの振分を責務とさせた

  • 配下の<domain>フォルダへ処理を投げてあげる
    • healthとaws-serviceが対象

domainフォルダは handler と executer で構成することで関心を分離させる

  • handler はHTTPメソッドとセカンドレベル以降のドメインの振分を責務とし、適切なexecuterを実行する
  • executer は dbフォルダに処理を投げる
    • dbフォルダへの事前/事後処理を責務とする
    • 実装していないが、validationがあったらこの辺りで処理させるといい感じかも

📁app/db配下

SQLの組み立てとSQL実行で責務を分けたい & DRYにしたかったので、
core.js#runSQLにコネクションのやり取りとSQLの実行を任せ、各DAOはSQLの構築に集中させた。

SQL組み立ては可能な限り1ファイル1SQLにすることで関心を分離できてそう

HTTP POST の処理

素のNode.jsだとHTTP POSTでbodyが受け取れなかった!
streaming でいい感じにできそうだったので、以下の処理を実装。

GET時には処理させたくないのでPromiseで書き、
合わせたほうがきれいだったのでPOSTもPromiseで実装した。

const readPostBody = (req) => {
  if (req.method !== "POST") {
    return Promise.resolve({});
  }
  return new Promise((resolve, reject) => {
    let body = "";
    req.on("data", (chunk) => {
      body += chunk.toString(); // Convert Buffer to string
    });
    req.on("end", () => {
      try {
        resolve(JSON.parse(body)); // Parse JSON string to object
      } catch (error) {
        reject(new Error("Invalid JSON format"));
      }
    });
    req.on("error", (error) => {
      reject(error);
    });
  });
};

所感

やっぱりフレームワークないと実装が煩雑に散らかるなあという気持ち。
とはいえ、素に近い状態でのNodejs x HTTPサーバに関する知見が増えたのはうれしい🙌

WebFramework n本ノック

https://zenn.dev/slopwelljp/articles/98b1ebf6604f58

Discussion