DOAP2023開発日記 #4
#3では、開発環境において、フロントエンドとバックエンドが別々の開発サーバになると、CORS問題が発生することを軽く触れた。create-react-appで作成したReactアプリの場合、package.jsonのproxy項目1つで済むことが、create-next-app(Next.js)では、パッケージを組み込んだりと多少面倒になる。
ここでは、おそらくいちばん面倒でないであろう方法を取る。
http-proxy
まず、http-proxyパッケージをインストールする。
# フロントエンド(next.js)ディレクトリ
$ npm i http-proxy
$ npm i -D @types/http-proxy
続いて、REST APIをプロキシする関数ファイルを作成する。
# フロントエンド(next.js)ディレクトリ
$ touch pages/api/[...path].ts
ちなみに、Next.jsでpages/apiの下に作成することを「API Routes」、「[…path].ts」の[]パスのことを「Dynamic Routes」という。
作成したpages/api/[…path].tsファイルを編集してデフォルト関数を定義する。
import { IncomingMessage as Request, ServerResponse as Response } from 'http';
import httpProxy from 'http-proxy';
const proxy = httpProxy.createProxyServer({
target: 'http://localhost:1337/',
changeOrigin: true
});
export default async function handler(req: Request, res: Response) {
return new Promise((resolve, reject) => {
proxy.web(req, res);
});
}
プロキシサーバ設定のプロキシ先を「http://localhost:1337/」とすれば、同一マシンのSails開発サーバ(デフォルトの時)にパススルーしてくれる。
ORMのマイグレーション設定
Sailsサーバを起動すると、ORMのマイグレーション設定をどうするか聞いてくる。毎回では大変なので、開発時のデフォルト設定をしておくと楽になる。
# config/local.js
module.exports = {
models: {
migrate: 'alter',
},
};
ORMのマイグレーション設定「migrate」値は、通常「config/models.js」内に書くが、「config/local.js」内に書くと、ローカル環境においてこの設定を優先してくれる。
余談だが、「config/local.js」は、「sails new」コマンドで作成したアプリケーションのひな形では「.gitignore」ファイルに含まれるので、Gitではバージョン管理対象外になる。この性質を利用して、ローカルでのみ使用したい、優先したい設定値をここに書けば、他のリポジトリに伝播させずに済む。例えば、ローカルだけで使いたいAPIキーなどでもいいわけだ。Sailsコード内で「sails.config.myapp.apikey='ABCD123'」という値を使いたい場合は、次のように設定する。
# config/local.js
module.exports = {
myapp: {
apikey: 'ABCD123',
},
};
Sailsサーバ起動
それでは、Sailsサーバ(バックエンド)を起動してみる。
# バックエンド(sails.js)ディレクトリ
$ npx sails lift
info: Starting app...
info: ·• Auto-migrating... (alter)
info: Hold tight, this could take a moment.
info: ✓ Auto-migration complete.
info:
info: .-..-.
info:
info: Sails <| .-..-.
info: v1.5.2 |\
info: /|.\
info: / || \
info: ,' |' \
info: .-'.-==|/_--'
info: `--'-------'
info: __---___--___---___--___---___--___
info: ____---___--___---___--___---___--___-__
info:
info: Server lifted in `/.../server2023`
info: To shut down Sails, press <CTRL> + C at any time.
info: Read more at https://sailsjs.com/support.
debug: -------------------------------------------------------
debug: :: Sun Jun 26 2022 14:16:55 GMT+0900 (GMT+09:00)
debug: Environment : development
debug: Port : 1337
debug: -------------------------------------------------------
#3と違い、Auto-migratingの設定値が自動でalter(1)が設定された状態で起動する。
Next.jsサーバ起動
続いて、Next.jsの開発サーバ(フロントエンド)を起動する。
# フロントエンド(next.js)ディレクトリ
$ npm run dev
> client2023@0.1.0 dev /.../client2023
> next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
event - compiled client and server successfully in 446 ms (125 modules)
プロキシテスト
バックエンド、フロントエンドの両サーバが起動したので、プロキシの設定がうまくいっているか確認する。ブラウザを開いて、Next.js側のポートでSailsサーバ側のAPI URL「http://localhost:3000/api/users/test?name=Hoge%20Hogeo」にアクセスしてみる。
問題ないようである。
今回はSails側のAPIを「/api/*」にすることで、Next.jsのAPI Routesを呼び出す「/api/*」と構造が一致していることで成り立っている。URL構造が一致しない時は、proxy.webに渡す直前にreq.urlをうまく書き換えればいいらしい。
まとめ
Next.jsでプロキシする方法を検索した時、どちらかというと「http-proxy-middleware」を使った方法が、ヒット数が多かった気がする。ただ、どれもこれも私にとってはわかりにくかったり、コード数が多かったりした。それに比べ、「http-proxy」の利用例は、コード数も少なく、わかりやすい部類だったので、こちらを参考にした。
もしかすると、場面によっては「http-proxy-middleware」の方がいいのかもしれないが、今回のような「http-proxy」を使った方法は、API Routesに頼らないAPI開発の中では、楽な部類だと思うので、まずはこの方法を試してみてほしい。