見出し画像

DOAP2023開発日記 #3

Next.jsには「API Routes」という、強力な「サーバーサイドAPIをクライアントサイドで開発する」機能がある。一カ所でSS/CS両方開発できるならそれに越したことはない。が、Next.jsに出会う前にSails.jsに出会っていて、Next.jsでごりごりするよりSailsが持っているいろいろな自動化機能の方が便利だな〜ってなって、私の中では、APIは「プロキシっちゃう」に限ると思っている。「こういう風にするとSailsと併用するのと同じか、より楽になる」ということを教えてくれる人がいれば、ご教授願いたい。
前置きはさておき、Next.jsのAPI RoutesはそのままProxyして、Sailsサーバに実装したAPIを呼び出す設定をする。

開発時のCORS問題

開発時に限っての話だが、Next.js×Sailsで開発する時、各々で開発サーバが起動する(デフォルトポートがNext.jsで3000番、Sailsで1337番の開発サーバ)。Next.jsサイトを開いているブラウザで別サーバ(と認識されるサイト)にリクエストすると、普通はCORS(Cross-Origin-Resourse-Sharing)違反となってエラーになる。通常はサーバ側が返すレスポンスヘッダで対応する案件だが、そもそもリリースする時にはNext.jsのリソースはSailsサーバにデプロイされ、同一サーバで動くので、最も面倒がない方法で開発したい。そこでhttp-proxyというパッケージを使って、開発時の面倒ごとをやり過ごすことにする。
ちなみに、create-react-appを使った開発時サーバでは、package.jsonに一行書くだけで済む("proxy": "http://localhost:1337")。
それでは、Sailsサーバに疎通確認用のAPIを立てる。

REST API自動化機能の設定

最初にconfig/blueprints.jsをエディタで開き、以下のパラメータを設定する。

module.exports.blueprints = {
  restPrefix: '/api',
  pluralize: true,
}

restPrefixはREST API用のパスにプレフィックスを付ける。例えばユーザ一覧をリクエストするのに、この指定がない時は「/users」となるところ、プレフィックスを付けると「/api/users」としないといけなくなる。Next.jsとの相互運用を考慮すれば、REST APIを「/api/*」で統一しておくことは有益だと思う。
もう一つの「pluralize」は、パスに複数形を使用するかどうかの指定になる。Userモデルの場合、blueprintsの機能で自動ルーティングされると、falseでは「/user」、trueでは「/users」がパスとして有効になる。これは好みかと思うが、特に日本人で、複数形がなじみのない名詞を使う時は気をつけた方がいい。

アクションの作成

次にコンソールで以下のようにコントローラとモデルを生成する。

$ npx sails generate api user

こうすると、コントローラapi/controllers/UserController.jsとモデルapi/models/User.jsが生成される。

このうち、コントローラに疎通確認用のアクションを追加する。api/controllers/UserController.jsを編集して、以下のようにする。

module.exports = {
  test: (req, res) => {
    return req.query.name
      ? res.ok({'Your name': req.query.name})
      : res.badRequest();
  }
};

Userコントローラにtestアクションを追加した状態になる。

ルーティングの設定

最後にルーティングを設定する。config/routes.jsファイルを編集して、次のようにする。

module.exports.routes = {
  '/': { view: 'pages/homepage' },
  '/api/users/test': 'UserController.test',
};

こうすることで、パス/api/users/testにUserController.testアクションが紐付く。いろいろ書き方があるが、このような左にパス、右にアクションメソッドが比較的簡単な書き方になる。

Sailsサーバ実行

ここまでできたらコンソールで以下のコマンドを実行する。

$ npx sails lift

実行を始めると、こんなことを聞いてきます。

 info: Starting app...

--------------------------------------------------------------------------------
 Excuse my interruption, but it looks like this app
 does not have a "migrate" setting configured yet.
 (perhaps this is the first time you're lifting it with models?)

 Tired of seeing this prompt?  Edit config/models.js.

 In a production environment (NODE_ENV=production) Sails always uses
 migrate:'safe' to protect against inadvertent deletion of your data.
 But during development, you have a few different options:

 1. FOR DEV:      alter   wipe/drop and try to re-insert ALL my data (recommended)
 2. FOR TESTS:    drop    wipe/drop ALL my data every time I lift Sails
 3. FOR STAGING:  safe    don't auto-migrate my data. I will do it myself

 Read more: sailsjs.com/docs/concepts/models-and-orm/model-settings#?migrate
--------------------------------------------------------------------------------

What would you like Sails to do this time?
 ** NEVER CHOOSE "alter" or "drop" IF YOU ARE WORKING WITH PRODUCTION DATA **

prompt: ?:

これは、Sailsに組み込まれているORM「Waterline」の起動時オプションで、1の「alter」を選択すると、モデルに紐付くテーブルを再構築するが、レコードデータもできるだけ引き継ごうとする(ただし保証はされない)。これは主に開発時に利用する。2の「drop」はテーブル/レコードすべてを一新するので、主にテスト環境で使用する。3の「safe」は、テーブル/レコードには一切影響を与えない。ステージングやプロダクション環境での利用が推奨される。今回は開発環境なので、ここでは、1を指定する。

prompt: ?:  1
--------------------------------------------------------------------------------
 OK!  Temporarily using migrate:'alter'...
 To skip this prompt in the future, edit config/models.js.
--------------------------------------------------------------------------------

 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 19 2022 14:44:30 GMT+0900 (GMT+09:00)

debug: Environment : development
debug: Port        : 1337
debug: -------------------------------------------------------

Sailsサーバが起動したら、まずはブラウザでhttp://localhost:1337/api/users/testにアクセスしてみる。

http://localhost:1337/api/users/test

エラーコード400が返ってくればOK。
次に、http://localhost:1337/api/users/test?name=Takahide%20Kondohにアクセスしてみる。

http://localhost:1337/api/users/test?name=Takahide%20Kondoh

正常レスポンスでJSONが返ってくればOK。

まとめ

さらっと説明してしまったが、SailsサーバはExpressをベースにWebサーバを構築するいろいろな機能、ORMや自動ルーティングなどがあり、それぞれ緩く統合されている。そしてそれらを比較的手軽な設定だけで使えるようになるのが魅力である。
そんなことをまあまあ丁寧に説明していたら、Next.jsまでいかなかった。次回とする。

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