NodeJS+MySQLで簡単なAPIサーバーを作る

こんちゃ!洋梨🍐です。

今回アプリでよくあるような「ランキング」を実装する方法についてになります。

以前の記事、LINEのような自作SNSアプリを開発した話 のサーバー部分を掘り下げたような内容になってます。

仕様

今回作るランキングサーバーの使用は以下の通りとします。

・http://[URI]/ <GET>でランキング上位10名をJSONで取得
・http://[URI]/ <POST>で情報の送信(id,scoreのJson形式)

※なお、今回ポートはウェルノウンポートでない3000を利用しています。

サーバー側

必要な主な作業を書いていきます。

CentOS上での事前準備

ファイアウォールの設定

[user@ed537ajo node]$ sudo firewall-cmd –add-service=http –zone=public –permanent
success
[user@ed537ajo node]$ sudo firewall-cmd –zone=public –list-services –permanent
ssh dhcpv6-client http

データベースを用意

ユーザーを追加

Create user testuser@localhost;

権限を付与

MariaDB [mysql]> grant all on test.* to testuser;
Query OK, 0 rows affected (0.00 sec)

データーベース「test」を作成し、データーベース「test」ができたことを確認

MariaDB [(none)]> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| test |
+——————–+

テーブル「RANK」を作成。

MariaDB [test]> show tables;
+—————-+
| Tables_in_test |
+—————-+
| RANK |
+—————-+
1 row in set (0.00 sec)

リクエストを処理するプログラムを作成

今回はNodeJs環境で実行するためにJavaScriptにて作成します。

const exp = require("express");
const bodyParser = require('body-parser');
const app = exp();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

const sql = require("mysql");
const con = sql.createConnection({
    user : "testuser",
    database : "test"
});

app.listen(3000,function(){
    console.log("Start Server.");
});

app.post("/",function(req,res,nex){
    const id = req.body.id;
    const score = req.body.score;
    const value = [id,score];
    console.log(req.body);
    console.log("Post : [id]"+id+" [score]"+score);

    con.query("SELECT * FROM RANK WHERE ID=?",value, async (e,r)=>{
        if(Object.keys(r).length){ // Find
            const aScore = r[0].score;
            console.log("Find ["+id+"] ["+aScore+"]");
            let result = {"result":"success","status":""};
            if(aScore < score) // 更新が必要
                if(!await update(score,id)) result.result = "failure";    
                else result.status = "update";
            else result.status = "no change";
            console.log("ok");
            res.send(result);
        }else{
            con.query("INSERT INTO RANK VALUE(?,?)",value,function(e,r){
                let result = {"result":"success","status":"create"};
                if(e) result.result="failure";
                res.send(result);
            });
        }
    });
});

function update(score,id){
    return new Promise(function(x){
        console.log("update");
        con.query("UPDATE RANK SET score=? where id=?",[score,id],(r,e)=>{
            x(e);
        });
    });
}

app.get("/",function(req,res,nex){
    console.log("Get");
    con.query("SELECT * FROM RANK ORDER BY score DESC LIMIT 10",(e,r)=>{
        res.json(r);
    });
})

クライアント側

今回は手っ取り早く実行できるUnity[C#]で作成します。

リクエストを送信するプログラムを作成

クライアント側はリクエストをPOSTで送信するだけのものです。

public class Main : MonoBehaviour
{
    public void PushPost()
    {
        Post("user2", 1234);
    }

    public async void Post(string id,int score)
    {
        Debug.Log("Post Request");
        string str = "{\"id\":\""+id+"\",\"score\":"+score+"}";

        var data = Encoding.UTF8.GetBytes(str);
        var req = WebRequest.Create("http://a.younaship.com:3000");
        req.Method = "POST";
        req.ContentLength = data.Length;
        req.ContentType = "application/json";
        using (var stm = req.GetRequestStream())
            await stm.WriteAsync(data, 0, data.Length);
        var res = await req.GetResponseAsync();
        using (var stm = res.GetResponseStream())
        using (var read = new StreamReader(stm))
            Debug.Log(await read.ReadToEndAsync());
    }
}

上のプログラムをアタッチし、ButtonのOnClick時にPushPost()を呼び出すようにすればボタンを押したときにリクエストが送信できます。

<試しにリクエストしてみる>

リクエスト送信前
Unityでリクエストを送信
リクエスト送信後

出来ていればPostした内容がしっかりと反映されていることが確認できます。

(受信したJsonを使用可能な形にする)

※こんなん知ってるからという人も多いと思うのですが一応書きます

受信したJSON形式の文字列をプログラムで使用可能にするためシリアライズします。なお、Unity上でシリアライズするのにはJsonUtilityを用います。なお.NET上ではSystem.Runtime.Serialization.Jsonを使うのがいいと思います。


    [SerializeField]
    public class Json
    {
        public string result;
        public string status;
    }    

    private void Conv(string json)
    {
        var j =(Json)JsonUtility.FromJson(json, typeof(Json));
        Debug.Log("結果:" + j.result);
        Debug.Log("ステータス:" + j.status);
    }

今回送信したリクエストに対するリスポンスのJSONは結果を確認する”result”、詳細情報を確認する”status”にしてあるのでそれを踏まえて作成するとこのようになります。

シリアライズして使う


今回はこんなところで終了です。また何かあれば新しく書こうと思います(^p^)

ここまで読んでくれてありがとうございました!!

ホームページでは他にも

・様々な記事や作った作品および過程
・ソースコード、素材ファイル
・あらゆる”モノ”の作り方

などなど随時、記事や作品を新規公開・更新していますので是非見ていってくださいね!見ていただけると本当に嬉しいです!

タグ: , , ,