2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ひとりJavaScriptAdvent Calendar 2022

Day 21

Express の基本をちゃんと理解する

Last updated at Posted at 2022-12-21

元々フロントエンドに惹かれてプログラミングを始めたこともありバックエンドには苦手意識があります。
今回の記事では少しでもバックエンドに親しむべく、普段何となく使っていた Express、そして Express が採用している API の形式である REST API について調べていきます。

API とは

API は Application Programming Interface の略です。
ソフトウェアが別のソフトウェアと通信するときの窓口を指します。

例えば React というライブラリにおいて state を管理する機能を利用するための窓口、 useState は API であると言えます。

また他のアプリが自分のサーバーにあるデータにアクセスできるようにしたもの(または他所のサーバーにあるデータにアクセスする手段)を特に Web API と言います。

REST API とは

RESTful API とも言われます。
「REST」は Representational State Transfer の略です。

Deepl

意味不明

API を設計するための手法、思想ですね。

Restful な API とは、

  • 全てのリソースが一意の識別子で識別されている
  • インターフェース(ユーザーがアクセスしてくるポイント)には規則がありシンプル
  • エンドポイントはリソースを表現していなければならず、URI を見るだけでどのような機能を持つのかがパッと分かるようにする
  • HTTP メソッド(GET, POST, PUT, PATCH, DELETE…)をその名の通りの役割で適切に使う
  • HTTP ステータスコードを適切に使う

といった規則をある程度守った API のことです。以下に例を示します。

NG🙅

/getitem
/modifyitem
/deleteitem
GET /item/:id
PATCH /item/:id
DELETE /item/:id

OK🙆

GET /items/:id
PATCH /items/:id
DELETE /items/:id
POST /customers/:id/orders

上の例では

  1. 商品の取得
  2. 商品の編集
  3. 商品の削除
  4. 顧客の注文を履歴へ追加

という4つの操作を行おうとしています。

REST API での正しい実装は「OK」の方です。別の操作に対し別のエンドポイントを用意するのではなく、同じエンドポイントに対して別の HTTP メソッドを使ってアクセスします。また HTTP メソッドが動きを表しているため、URI に動詞を入れる必要はありません。

また全てのリソースは id で管理されているはずなので、特定の商品にアクセスするために id が使えます。

そして item ではなく items複数形を使うようにしましょう
もしかしたら商品は全部で1点しかないかもしれませんが、REST API では複数形で定義することがルールとなっています。その方が「複数の中から1つを選んで操作するよ」というふうに意味が通りやすいですよね。

最後に POST の例では /customers/:id/orders というふうに URI が階層になっています。「顧客/このID/全ての注文」という感じですね。このような書き方を ネスト といい、これも RESTful な API の特徴です。

Express とは

Node.js でサーバーを簡単に作成できるフレームワークです。

Express - Node.js web application framework

Express の設定を理解する

Express でサーバーを立てる最も簡単な例としては以下のようになります。

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

// 引用: https://expressjs.com/en/starter/hello-world.html

上のコードは公式サイトから引用しました。
Express の開発陣はセミコロンつけない派なんですね。

この状態で js ファイルを実行すれば http://localhost:3000/ でサーバーが立ち上がります。

localhost:3000 のスクショ

しかしまあこの辺は設定呪文だと思っていつもほぼコピペしていました。今回はきちんと内容を見ていきます。

const express = require('express')

npm や yarn でインストール済みの express を 変数「express」としてrequire してこのファイルで使えるようにしています。

const app = express()

express のインスタンスを app に格納しています。
今後この app で使えるメソッドを使って express のサーバーを設定していきます。

app.get('/', (req, res) => {
  res.send('Hello World!')
})
  1. app.get : 第1引数の URI に対し、get メソッドでアクセスがあった場合に第2引数の関数が動く
  2. req : リクエストオブジェクトが入る引数
  3. res : レスポンスオブジェクトが入る引数
  4. res.send : 引数に入っている文字列を返すメソッド
app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

applisten メソッドを使い、第一引数にポートを設定し、第二引数にサーバー立ち上げ時に実行したい関数を渡してサーバーを起動します。サーバーがきちんと動いていることを確かめるためコンソール出力するといいでしょう。

第一引数のポートは直書きでもいいのですが、デプロイしたり他の人の手元で動かしてもらったりすることを考えると環境変数に対応させておいた方がいいでしょう。

const express = require('express')
const app = express()

// 環境変数で起動するが、指定がなければ localhost 3000 で立ち上げる
const port = PROCESS.ENV.PORT || 3000 

app.get('/', (req, res) => {
  res.send('Hello World!')
})

// 変数で指定されているので様々なケースに対応できる
app.listen(port, () => { 
  console.log(`Example app listening on port ${port}`)
})

// 引用: https://expressjs.com/en/starter/hello-world.html

他の HTTP メソッドを使う

app.METHOD の形で以下の HTTP メソッドを使えます。

checkout
copy
delete
get
head
lock
merge
mkactivity
mkcol
move
m-search
notify
options
patch
post
purge
put
report
search
subscribe
trace
unlock
unsubscribe

Express 4.x - API Reference

中でも本当によく使うのは以下でしょう。

  • app.delete
  • app.get
  • app.patch
  • app.post
  • app.put

また全ての HTTP リクエストに対応する app.all メソッドもあります。

app.all('/secret', (req, res, next) => {
  console.log('Accessing the secret section ...')
  next() // pass control to the next handler
})

パスパラメータを渡す

パスの一部には任意の入力を受け取れるパスパラメータを設定できます。

app.get('/users/:userId/books/:bookId', (req, res) => {
  res.send(req.params)
})
// 引用: https://expressjs.com/en/guide/routing.html

上の例の場合、パスは /users/:userId/books/:bookId となっています。例えば http://localhost:3000/users/34/books/8989 というふうにアクセスしたとしましょう。

すると req オブジェクトの params = req.params には { "userId": "34", "bookId": "8989" } というオブジェクトが入ります。

「userId が 34 で、bookId が 8989 のリソースに対するアクセスだな」と解析できるわけです。

クエリパラメータを渡す

パスパラメータとは違い、任意の入力として渡すわけではなく URI の末尾に追加情報としてくっつけます。省略可能です。

app.get('/users/:userId/books/?sort=true', (req, res) => {
  res.json(data)
})

例えば上のような使い方があるでしょう。ここでは「データを昇順にソートしてね」という条件を付与していますが、ソートは省略可能です。

他に検索やフィルタにも使えますね。Amazon のリンクにもたくさんのクエリパラメータがあるのを見つけられると思います。

ミドルウェアの使用

app.use メソッドを使うことでミドルウェアを使用することができ、通常盤の Express では使えないたくさんの便利な機能が使えます。

自分でパスと関数を指定することもできますし、Express から公式提供されているものも使えます。

app.use('/user/:id', (req, res, next) => {
  console.log('Request Type:', req.method)
  next()
})

// 引用: http://expressjs.com/en/guide/using-middleware.html
app.use(express.json()) // json を解析する

まとめ

  • API はソフトウェアが別のソフトウェアと通信するときの窓口
  • RESTful API は以下のような規則をある程度守っている API:
    • 全てのリソースが一意の識別子で識別されている
    • インターフェース(ユーザーがアクセスしてくるポイント)には規則がありシンプル
    • エンドポイントはリソースを表現していなければならず、URI を見るだけでどのような機能を持つのかがパッと分かるようにする
    • HTTP メソッド(GET, POST, PUT, PATCH, DELETE…)をその名の通りの役割で適切に使う
    • HTTP ステータスコードを適切に使う
  • express は app.METHOD の形で多くの HTTP メソッドを使うことができ、 app.listen で起動できる
  • パスの一部には任意の入力を受け取れるパスパラメータを設定できる
  • 任意の入力としてクエリパラメータを設定できる
  • ミドルウェアを使用することで、通常盤の Express では使えないたくさんの便利な機能が使える

参考資料

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?