2
0

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.

Express.jsを利用してミニマムなローカルサーバを構築するサンプル

Last updated at Posted at 2023-10-23

はじめに

Web系エンジニアが検証やハッカソンでミニマムなCRUDのAPIを用意する際に便利なExpress.jsについてまとめてみることにしました。

前提

  • データストアとしてはローカルファイル(.json)を利用します
  • body-parserを利用します
  • node, npmが利用できること
  • Expressの説明はしません。
  • curlでHTTPリクエストを検証します

まとめ

先にサンプルコード全体を記載します。

const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs')

const app = express();
app.use(bodyParser.json());

const fileName = 'todos.json';

// GET /todos
app.get('/todos', (req, res) => {
    fs.readFile('todos.json', 'utf8', (err, data) => {
        if (err) throw err;
        res.send(JSON.parse(data));
    });
});

// POST /todos
app.post('/todos', (req, res) => {
  const newTodo = req.body;
  fs.readFile('todos.json', 'utf8', (err, data) => {
    if (err) throw err;
    const todos = JSON.parse(data);
    todos.push(newTodo);
    fs.writeFile('todos.json', JSON.stringify(todos), (err) => {
        if (err) throw err;
        res.status(201).send(newTodo);
    });
  });
});

// PUT /todos/:id
app.put('/todos/:id', (req,res) => {
  const id = parseInt(req.params.id);
  const updatedTodo = req.body;
  fs.readFile('todos.json', 'utf8', (err,data) => {
    if (err) throw err;
    const todos = JSON.parse(data);
    const index = todos.findIndex(todo => todo.id === id);
    todos[index] = updatedTodo;
    fs.writeFile('todos.json', JSON.stringify(todos),(err) => {
      if(err)throw err;
      res.send(updatedTodo);
    });
  });
});

// DELETE /todos/:id
app.delete('/todos/:id',(req,res) => {
  const id = parseInt(req.params.id);
  fs.readFile('todos.json','utf8',(err,data) => {
    if(err) throw err;
    let todos = JSON.parse(data);
    todos = todos.filter(todo => todo.id !== id);
    fs.writeFile('todos.json', JSON.stringify(todos),(err) => {
      if(err) throw err;
      res.status(204).send();
    });
  });
});

// Server Configuration
const port = 3000;
app.listen(port, ()=> {
  console.log(`Server is running at http://localhost:${port}`);
})

やってみたこと

必要なライブラリのインストール

まずはexpressを利用するのでそれを入れます。

また、参照系以外のAPIではローカルファイルにjson形式でデータを読み書きしたいので、パーサとして利用するbody-parserを入れておきます。ファイルアクセスにfsを利用しますが、ビルトインのライブラリのためインストールはしません。

$ npm init -y
$ npm install express --save
$ npm install body-parser --save

app.jsの作成 1/n

簡単なToDoアプリケーションでの利用を想定して、CRUDのAPIを用意します。

まずはGETリクエストが通るところまで書いていきます。

const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs')

const app = express();
app.use(bodyParser.json());

// GET /todos
app.get('/todos', (req, res) => {
  fs.readFile('todos.json', 'utf8', (err, data) => {
    if (err) throw err;
    res.send(JSON.parse(data));
  })
})

// POST /todos

// PUT /todos:id

// DELETE /todos:id

// Server Configuration
const port = 3000;
app.listen(port, ()=> {
  console.log(`Server is running at http://localhost:${port}`);
})

その後、データ永続化用のjsonファイルを空で作成した上で起動します。

$ echo "[]" > todos.json
$ node app.js

コマンド実行後、curlでGETアクセスして空配列が帰ることを確認します

$ curl -X GET http://localhost:3000/todos
[]$

app.jsの作成 2/n

次に残りのPOST, PUT, DELETEも埋めていきます。

  • POST

    // POST /todos
    app.post('/todos', (req, res) => {
      const newTodo = req.body;
      fs.readFile('todos.json', 'utf8', (err, data) => {
        if (err) throw err;
        const todos = JSON.parse(data);
        todos.push(newTodo);
        fs.writeFile('todos.json', JSON.stringify(todos), (err) => {
            if (err) throw err;
            res.status(201).send(newTodo);
        });
      });
    });
    
  • PUT

    // PUT /todos/:id
    app.put('/todos/:id', (req,res) => {
      const id = parseInt(req.params.id);
      const updatedTodo = req.body;
      fs.readFile('todos.json', 'utf8', (err,data) => {
        if (err) throw err;
        const todos = JSON.parse(data);
        const index = todos.findIndex(todo => todo.id === id);
        todos[index] = updatedTodo;
        fs.writeFile('todos.json', JSON.stringify(todos),(err) => {
          if(err)throw err;
          res.send(updatedTodo);
        });
      });
    });
    
  • DELETE

    // DELETE /todos/:id
    app.delete('/todos/:id',(req,res) => {
      const id = parseInt(req.params.id);
      fs.readFile('todos.json','utf8',(err,data) => {
        if(err) throw err;
        let todos = JSON.parse(data);
        todos = todos.filter(todo => todo.id !== id);
        fs.writeFile('todos.json', JSON.stringify(todos),(err) => {
          if(err) throw err;
          res.status(204).send();
        });
      });
    });
    

テスト

curlコマンドを利用してデータの新規作成・変更・削除・参照ができるか確認します。

以下のコマンドを上から実行して、最終的に空配列が返る状態になっていれば期待動作しています。

curl -X POST -H "Content-Type: application/json" -d '{"id": 1, "title":"test"}' http://localhost:3000/todos
curl -X GET http://localhost:3000/todos
curl -X PUT -H "Content-Type: application/json" -d '{"id": 1, "title":"updated test"}' http://localhost:3000/todos/1
curl -X DELETE http://localhost:3000/todos/1
curl -X GET http://localhost:3000/todos

最後に

JavaScriptでライトなAPIサーバをローカルに立てる際にExpressをよく使いますが、毎回同じような内容を書いているのと、ハッカソンで意外と分担に困って突然APIを立てる役になったけど慣れてないので焦って時間取られる、ということがたまにありましたので、すぐに取り出してコピペできるように備忘録も兼ねて記事化してみました。

急いでいるだれかの参考になれば幸いです。

参考

2
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?