TypeScriptとExpressでCRUD API開発!初心者向け超入門サンプル
生徒
「TypeScriptとExpressを使って、データの追加や削除ができるWebプログラムを作りたいのですが、やり方がわかりません。」
先生
「TypeScriptとExpressを組み合わせると、データの追加、読み込み、更新、削除といった基本機能を持つ、高性能なプログラムを簡単に作ることができますよ。」
生徒
「具体的にはどのように仕組みを作って、プログラムを書けば良いのですか?」
先生
「それでは、開発の準備から実際のプログラムの書き方まで、一歩ずつ順番に見ていきましょう!」
1. クラウドやサーバー開発で重要なCRUDとExpressとは?
日常のパソコン操作やスマートフォンのアプリでは、常にデータのやり取りが行われています。例えば、SNSで新しい投稿を作成したり、過去の投稿を読んだり、内容を編集したり、不要になった投稿を消去したりする操作です。これらの仕組みは、インターネットの世界ではバックエンド開発やサーバーサイド開発と呼ばれており、すべての基本となるのがCRUDという考え方です。CRUDとは、データの作成(Create)、読み込み(Read)、更新(Update)、削除(Delete)の頭文字を並べた言葉です。どのような複雑なWebアプリケーションであっても、基本はこの4つの動作の組み合わせで成り立っています。
今回は、このデータ操作を行うための仕組みであるAPIを、TypeScriptという最先端のプログラミング言語と、Node.jsの上で動作するExpressという人気のフレームワークを使って作っていきます。APIとは、アプリケーション同士が通信をしてデータをやり取りするための窓口のようなものです。Expressは、インターネットからの要求を受け取って、適切な返事を返す処理を驚くほど簡単に記述できる便利な道具です。プログラミングが初めての人でも、データの流れを一つずつ追いかければ必ず理解できるようになります。まずは全体の流れを掴んでいきましょう。
2. 開発環境の準備と必要なツールのインストール方法
プログラムを作成して動かすためには、パソコンに必要な道具をいくつか導入する必要があります。まずは、JavaScriptやTypeScriptのプログラムをパソコン上で実行するための基盤となるNode.jsをインストールします。Node.jsを導入すると、パッケージ管理ツールであるnpmという道具も一緒に使えるようになります。npmは、世界中の開発者が作った便利なプログラムの部品を、自分のパソコンに自動でダウンロードして組み込んでくれる大変優れた仕組みです。
環境を整えるためには、まずパソコンのコマンドプロンプトやターミナルと呼ばれる文字を入力する画面を開きます。そして、新しくプログラムを作成する専用のフォルダを作り、その中で初期化の命令を実行します。これにより、プロジェクトの設定ファイルが自動的に生成されます。続いて、今回使用するExpressと、TypeScriptを動かすために必要な周辺ツールをまとめてインストールします。初心者の方でも、指定された命令を一行ずつ入力していけば簡単に準備を進めることができます。
3. 最初に作成する設定ファイルの内容を確認しよう
TypeScriptを使って開発を行う際は、プログラムを動かす前に、どのようにTypeScriptを解釈して実行するかを決める設定ファイルが必要になります。この設定ファイルは「tsconfig.json」という名前のテキストファイルで管理されます。設定ファイルの中では、作成したプログラムファイルをどこに保存するか、どのバージョンの機能を使用するかといった、細かいルールを記述します。
この設定を正しく行うことで、入力ミスを事前に発見してくれるTypeScriptの強力な機能が有効になります。プログラムを書き始める前に、この土台となる設定ファイルをプロジェクトのフォルダの直下に作成しておきましょう。今回は、初心者でも最も扱いやすい標準的な設定内容を用意しました。このファイルを配置することで、これから記述するExpressのプログラムが正常に解釈されるようになります。
4. データを保存する配列と初期状態のプログラム
今回は、データベースの代わりに、パソコンのメモリ上にデータを一時的に保存する「配列」という仕組みを使ってデータを管理します。配列とは、複数のデータを一列に並べて保管できる箱のようなものです。今回は、本の情報を管理するWebアプリケーションを想定して、本の識別番号、本のタイトル、著者名の3つの情報を持ったデータを扱います。
まずは、どのようなデータの形にするかをTypeScriptの機能である「インターフェース」を使って定義します。インターフェースとは、データの設計図や自己紹介カードのようなもので、この形以外のデータが紛れ込むのを防ぐ役割を持っています。それでは、最初にExpressの基本的な設定を行い、データが空っぽの状態で起動するプログラムの土台を書いてみましょう。
import express from 'express';
interface Book {
id: number;
title: string;
author: string;
}
const app = express();
app.use(express.json());
let books: Book[] = [
{ id: 1, title: "はじめてのTypeScript", author: "山田太郎" },
{ id: 2, title: "Express入門", author: "鈴木花子" }
];
app.listen(3000, () => {
console.log("サーバーがポート3000で起動しました");
});
上記のプログラムでは、まずExpressを読み込み、データの設計図となるインターフェースを定義しています。そして、2冊の本のデータを最初から入れた配列を用意しています。「app.use(express.json())」という行は、インターネットを通じて送られてきた文字データを、プログラムで扱いやすい形式に自動で変換するための重要な設定です。最後の行で、ポート番号3000番という窓口を開放して、いつでも通信を受け付けられる状態にしています。
5. データを取得するRead機能の実装と解説
それでは、CRUDの「R」にあたる、データを読み込む処理を追加していきましょう。インターネットの通信では、データを取得したいときに「GET」という命令の種類を使用します。今回は、登録されている本の一覧をすべて取得する処理と、特定の識別番号を指定して1冊だけの詳細な情報を取得する処理の2パターンを作成します。
特定の1冊を探すときには、配列の中に用意されている便利な機能を使って、指定された識別番号と一致するデータを検索します。もし見つからなかった場合は、「データが見つかりませんでした」というエラーのメッセージと、通信が失敗したことを表す番号を相手に返すように作ります。これにより、利用者は正しく操作できたかどうかが一目でわかるようになります。
// 全ての本のデータを取得する処理
app.get('/api/books', (req, res) => {
res.json(books);
});
// 特定の本のデータを1件だけ取得する処理
app.get('/api/books/:id', (req, res) => {
const bookId = parseInt(req.params.id);
const book = books.find(b => b.id === bookId);
if (!book) {
return res.status(404).json({ message: "指定された本は見つかりません" });
}
res.json(book);
});
このプログラムでは、URLの形式に応じて処理を分けています。「/api/books」にアクセスがあった場合は、持っている本の配列をそのまま送り返します。「/api/books/:id」のように後ろに数字がついた場合は、その数字を識別番号として認識します。画面から送られてくる情報は最初は文字列という文字の集まりになっているため、「parseInt」という機能を使って数字のデータに変換してから、配列の中身を検索しています。
6. 新しいデータを追加するCreate機能の実装と解説
次に、CRUDの「C」にあたる、新しいデータを新しく追加する処理を作ります。新しくデータを送信して登録を依頼するときは、インターネットの通信では「POST」という命令の種類を使用します。画面から新しい本のタイトルと著者名が送られてくるので、プログラム側で新しい識別番号を自動的に割り振って、配列の一番最後に追加します。
データが追加されたら、正しく登録が完了したことを表す成功の番号と一緒に、新しく作られた本の内容を返してあげます。これにより、追加したデータがどのような形で保存されたのかを確認することができます。それでは、実際のプログラムコードを確認していきましょう。
// 新しい本を登録する処理
app.post('/api/books', (req, res) => {
const { title, author } = req.body;
if (!title || !author) {
return res.status(400).json({ message: "タイトルと著者名は必須です" });
}
const newBook: Book = {
id: books.length + 1,
title: title,
author: author
};
books.push(newBook);
res.status(201).json(newBook);
});
この処理では、「req.body」という場所から、送られてきたデータの情報を取り出しています。もしタイトルや著者名が空っぽだった場合は、不完全なデータとして処理を中断し、「必須です」という警告メッセージと、操作が間違っていることを意味する「400」という番号を返します。問題がなければ、現在の配列の長さを利用して新しい識別番号を作り、「push」という命令で配列にデータを追加しています。成功したときは「201」という作成完了の番号を返します。
7. 既存のデータを書き換えるUpdate機能の実装と解説
続いて、CRUDの「U」にあたる、すでに登録されているデータの内容を書き換える更新処理を追加します。データを上書きして更新を指示するときは、「PUT」という命令の種類を使用します。更新の際は、どのデータを変更するかを指定するための識別番号と、新しく書き換えるための内容の2つの情報が必要になります。
処理の流れとしては、まず指定された識別番号の本が配列の中に存在するかどうかを調べます。存在した場合は、その本の内容を送られてきた新しいタイトルや著者名に変更します。もし指定された番号の本がなければ、読み込み処理のときと同じようにエラーを返します。実際のプログラムは以下のようになります。
// 本の情報を更新する処理
app.put('/api/books/:id', (req, res) => {
const bookId = parseInt(req.params.id);
const book = books.find(b => b.id === bookId);
if (!book) {
return res.status(404).json({ message: "更新する本が見つかりません" });
}
const { title, author } = req.body;
if (title) book.title = title;
if (author) book.author = author;
res.json(book);
});
このプログラムでは、見つかった本のデータを直接書き換えています。「if (title)」という記述を使うことで、もし新しいタイトルが送られてきていれば上書きし、送られてきていなければ元の内容をそのまま維持するという、親切な設計にしています。最後に、新しく更新された後の本のデータを画面に送り返して処理が完了します。
8. データを削除するDelete機能の実装と解説
最後に、CRUDの「D」にあたる、不要になったデータを削除する処理を作ります。データを削除するときは、その名の通り「DELETE」という命令の種類を使用します。削除したい本の識別番号をURLで指定してもらい、その番号に該当する本を配列の中から取り除きます。
配列から特定の要素を消去する方法はいくつかありますが、今回は「指定された番号以外のデータだけを集めた新しい配列を作り直す」という安全な方法を採用します。これにより、目的のデータだけを綺麗に消し去ることができます。それでは、最後の機能のプログラムを見てみましょう。
// 本のデータを削除する処理
app.delete('/api/books/:id', (req, res) => {
const bookId = parseInt(req.params.id);
const bookExists = books.some(b => b.id === bookId);
if (!bookExists) {
return res.status(404).json({ message: "削除する本が見つかりません" });
}
books = books.filter(b => b.id !== bookId);
res.json({ message: "本のデータを削除しました" });
});
ここでは「some」という機能を使って、削除したい番号の本が本当に存在するかを事前に確認しています。存在しない場合はエラーを返します。存在した場合は、「filter」という機能を使って、削除したい番号とは一致しない本だけを抽出した新しい配列を作り、それを元の「books」という変数に代入し直しています。これにより、指定した番号の本だけが消滅した状態を作ることができます。
9. 完成したプログラムの動かし方と動作確認の手順
これまでに解説したすべてのプログラムを一つのファイルにまとめることで、本格的なデータ操作ができるAPIの仕組みが完成します。プログラムを実行するには、まずTypeScriptのプログラムを、パソコンが理解できる通常のJavaScriptの形式に変換する必要があります。この変換作業を「コンパイル」と呼びます。
コンパイルが完了すると、新しく実行用のファイルが作られます。それをNode.jsの命令を使って起動すると、画面にサーバーが起動したことを示すメッセージが表示され、インターネットからの接続を待ち受ける状態になります。この状態で、専用のテストツールやブラウザを使って決められたURLにアクセスすることで、データの追加や削除の動きを実際に目で見て確認することができます。
サーバーがポート3000で起動しました
このように黒い画面に起動のメッセージが表示されれば、プログラムは正常に動作しています。プログラムが起動している間は、パソコンがいつでも要求に応えられる受付窓口になっています。途中で終了したい場合は、キーボードの特定のボタンを押すことで、いつでも安全に停止させることができます。これで、TypeScriptとExpressを用いた最も基本的なデータ操作の仕組みづくりをすべて学ぶことができました。この基礎を応用することで、スマートフォンのアプリや様々なWebサービスの開発へとステップアップしていくことが可能です。