LoginSignup
3
3

More than 5 years have passed since last update.

ES6過渡期のMithril入門 ③WebフレームワークKoaにPOST

Last updated at Posted at 2015-11-06

0) 今回は、web連携最初の関門、POST

先人のおかげで、あまり苦労せず。Expressに比べ、モジュール選定の自由が高い分、あちこち調べながらとはなったが。あと、Curlのお勉強も必要となった。

1) MithrilのPOST関係コードを見る

Mithril黒ムツ本(というらしい)のサンプルのうち、2章のToDo3を参考にする。
MVVMモデルのMithrilということで、追加ボタンを押した後、

[View]
- m("input", {onchange: m.withAttr("value", vm.description), value: vm.description()})
- m("button", {onclick: vm.add}, "追加")
[ViewModel]
- vm.add = function (){ ... Todo.save(vm.list())...}
[Model]
- Todo.save = function...

の順に、メソッドが呼ばれサーバへのPOSTが行われる。Mithtil APIのm.requestを用い、dataコレクションを送付:

引用元=github.com/oreilly-japan/mithril-book-sample/blob/master/chapter02_tutorial/todo3/client/app.js
// サーバに現在のタスクを送信
Todo.save = function (todoList) {
    var data = todoList.filter(function (todo) { return !todo.done(); });
    m.request({method: "POST", url: "/tasks", data: data});
};

受け側のexpressコードは以下:

引用元github.com/oreilly-japan/mithril-book-sample/blob/master/chapter02_tutorial/todo3/server.js
app.post("/tasks", function (req, res) {
    console.log("post tasks");
    fs.writeFileSync("todo.json", JSON.stringify(req.body));
    res.status(200).end();
});

req.bodyはJSONの配列で、これを、fsモジュールより、ローカルファイルのtodo.jsonに書き出している。

m.requestによる呼び出しに対応するcurlは以下:

curl localhost:8000/tasks -H 'Content-Type: application/json' --data-binary '[{"description":"入力内容","done":false}]'
cf. Curlどう書くんだっけ?という時は、こちらを参考: WebAPIリクエスト仕様書としてcurlコマンドのご提案

doneは、ToDoのチェックがされたかどうか(true/false)。

2) KoaでMithrilからのPOSTを受ける。

ということで、上記のcurlリクエストを受けるKoaコードを書いてみる。

まずは、今回の作業に必要となりそうな、Koaのモジュールを改めて導入。

npm init
npm install koa koa-router koa-bodyparser koa-json koa-static co-views jade fs --save

このうち、koa-bodyparser がPOSTされたbodyをパースしてくれる。本質コードは、これだけ:

router.post '/', (next)->
    fs.writeFileSync "todo.json",JSON.stringify(@request.body)
  yield next

curlの--data-binary以下から送付された内容(ここではJSON配列)が、@request.bodyに格納されるので、その内容をファイルに書き出す。

今回から、よく出来たラウター・モジュールとして、koa-routerを導入。
結果、app本体部分は以下のコードに:

app.coffee
koa = require 'koa'
api = do require 'koa-router'
serve = require 'koa-static'

api.use '/tasks', require './api/tasks' 
#/tasksへのリクエストは./api/task.coffeeにて処理

app = koa()
app
.use do require 'koa-bodyparser'
.use do require 'koa-json'
.use api.routes()
.use api.allowedMethods()
.use serve __dirname + '/static' #静的HTMLは、/static以下に置く。
.listen 3000

ToDoタスクの登録・一覧部分のコード:

/api/task.coffee
router = do require 'koa-router'
fs = require "fs"

# `POST /tasks` = タスク登録(todo.jsonに書き出し)
router.post '/', (next)->
    console.log "post tasks"
    fs.writeFileSync "todo.json",JSON.stringify(@request.body)
  yield next

# `GET /tasks` = タスク一覧(todo.jsonから読み出し)
router.get '/', (next)->
    console.log "get tasks"
    docs =  JSON.parse fs.readFileSync("todo.json", "utf8")
    @body = docs
    yield next

module.exports = router.routes()

koa-routerのおかげで、コードも適切にモジュール化され、めでたしめでたし。
・・・で終わりにしたかったのだが、router.post~yield nextだけでは、タスク一覧の更新をよろしくやってくれないらしい(ブラウザ画面をリフレッシュすると、更新されたタスク一覧が表示される)。このあたり、Mithril側の責務だと思うが、次回への宿題とする。

3) 次回以降

Mithrilとkoa-routerの組み合わせをマスターすると共に、mongodbあたりへの永続化を行う。
ここまでできたら、全体をgithubに上げることとしたい。

koa-routerとKoaでのmongoの扱いについては、先人:koaでjsonwebtokenを使っていい感じに認証するが、自前認証モジュール含め、かなりいい感じ。Thanks!

3
3
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
3
3