1. 登録すると201で、id は DB が決める
  2. 名前が空なら400
  3. 登録していないときの一覧は1件のまま
コース一覧
Node.js入門
出品をDB化

Node.js入門

Node.jsの実行モデル、npm、Expressによるルーティング、REST API設計、データベース接続、トランザクションを使った購入処理、トークン認証まで、バックエンド開発の基礎を、毎レッスン実際にコードを書き、フリマアプリのAPIを自分の手で作りながら学びます。

1
Node.jsとは
01. Node.jsとは15分
02. スクリプトを実行する15分
03. npmとは15分
04. package.json15分
05. npmスクリプト15分
06. つくる:プロジェクト始動20分
07. 第1章クイズ10分
2
モジュールと非同期の復習
01. import/export15分
02. ファイルを読み書きする15分
03. async/await復習15分
04. JSONの取り回し15分
05. つくる:データ層20分
06. 第2章クイズ10分
3
はじめてのサーバー
01. サーバーとリクエスト15分
02. Expressを導入する15分
03. ルーティング15分
04. JSONを返す15分
05. 開発の回し方15分
06. つくる:サーバー始動20分
07. 第3章クイズ10分
4
REST APIのきほん
01. RESTの考え方15分
02. 一覧を返す15分
03. 1件を返す15分
04. 登録を受ける15分
05. 更新と削除15分
06. ステータスコード15分
07. つくる:商品CRUD完成20分
08. 第4章クイズ10分
5
リクエスト処理と検証
01. クエリパラメータ15分
02. 並び替えとページング15分
03. 入力検証15分
04. ミドルウェア15分
05. エラーハンドリング15分
06. つくる:検索API完成20分
07. 第5章クイズ10分
6
データベース接続
01. DBにつなぐ15分
02. 一覧・詳細をDB化15分
03. 出品をDB化15分
04. SQLインジェクション20分
05. 更新・削除をDB化15分
06. 購入トランザクション20分
07. つくる:DB版fleama20分
08. 第6章クイズ10分
7
認証のきほん
01. 認証と認可15分
02. パスワードハッシュ15分
03. ログインとトークン15分
04. 保護ルート15分
05. 本人のものだけ15分
06. つくる:認証完備20分
07. 第7章クイズ10分
8
総合制作
01. fleama API完成20分
02. Reactと接続する20分
03. サーバーで常駐させる20分
04. 自由拡張20分
05. 完成と次のステップ15分

出品をDB化

書き込みは run で行う

読み出しの get と all に続いて、書き込みの run を使います。

JavaScript

const result = db .prepare("INSERT INTO items (name, price) VALUES (?, ?)") .run("レザースニーカー", 4800);

? の場所に、run に渡した値が順番どおりに入ります。この ? をプレースホルダと呼びます。次のレッスンで、これが単なる書き方の都合ではないことを見ます。

id はデータベースが決める

第4章では「最大の id + 1」を自分で計算していました。表を AUTOINCREMENT で作っておけば、その計算は要りません。

JavaScript

const result = db.prepare("INSERT INTO items (name, price) VALUES (?, ?)").run(name, price); const newId = result.lastInsertRowid;

lastInsertRowid に、いま入った行の id が返ります。

自分で計算しないほうが安全です。2 人が同時に出品したとき、自分で計算する方式だと両方が同じ id を掴むことがあります。データベースに任せれば、そこは正しく捌かれます。

数として扱う

lastInsertRowid は、とても大きな数まで扱える特別な形で返ります。そのまま JSON にすると扱いにくいので、数値に直します。

JavaScript

const newId = Number(result.lastInsertRowid);

入れたものを返す

登録の応答には、作られたものを返します。id が決まるのは登録した後なので、入れてから読み直すのが確実です。

JavaScript

const newId = Number(result.lastInsertRowid); const created = db.prepare("SELECT id, name, price FROM items WHERE id = ?").get(newId); res.status(201).json(created);

手元の値から組み立てても同じに見えますが、DEFAULT 0 のようにデータベース側が決めた値は読み直さないと分かりません。

検証は変わらず入り口で

第5章で書いた検証は、そのまま前に残します。

JavaScript

if (!req.body.name) { return res.status(400).json({ error: "商品名は必須です" }); }

データベースにも制約は付けられますが、おかしな入力は入り口で止めるのが先です。400 で理由を返すほうが、送った側にとって分かりやすくなります。

手を動かす

演習では、出品をデータベース書き込みに置き換えます。id はデータベースに決めさせてください。

要件

  1. name が空なら 400 で {"error":"商品名は必須です"} を返す
  2. INSERT はプレースホルダ ? を使い、id は AUTOINCREMENT に任せる
  3. 入った id で読み直した {id, name, price, sold} を 201 で返す

入出力例

request("POST", "/items", {"name":"木製のスツール","price":3500}) → "201 {"id":2,"name":"木製のスツール","price":3500,"sold":0}" request("POST", "/items", {"name":"","price":3500}) → "400 {"error":"商品名は必須です"}" request("GET", "/items") → "200 [{"id":1,"name":"レザースニーカー","price":4800,"sold":0}]"

ヒント

検証の `if` を先に書き、その後で `INSERT` します

`db.prepare("INSERT INTO items (name, price) VALUES (?, ?)").run(名前, 価格)` の形です

`result.lastInsertRowid` を `Number(...)` に通してから、その id で読み直します

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/10

関連レッスン

  • SQLインジェクション

    文字列連結の危険を再現してから直し、プレースホルダが必要な理由を説明できるようになります。

  • 更新・削除をDB化

    編集と取下げをDB化し、変更系を移行できるようになります。

  • 購入トランザクション

    売切れ化と購入記録を不可分にし、複数の更新を一括で処理できるようになります。

  • つくる:DB版fleama

    全APIをDBで動かし、データ層を丸ごと移行できるようになります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • プレースホルダSQL の `?` 部分にあとから値を入れる仕組み
  • データベースデータを構造化して保存する仕組み
  • applicationJSON 本文を送るときの Content-Type
main.js
学習モード
エディタを読み込んでいます

メモ

出品をDB化

⌘S で保存