目的
前回 Python で書いた JSON ファイルを出入力する API を Node.js に書き換える。
書いた
Python の Flask 代わりに Node.js の Express を使いました。
前回 Python で書いた API をそのまま Coffee に書き換えただけです。URI は 前回の と全く同じです。
非同期なので I/O のところを Deffered 使いましたが、あとでリファクタします。書いてみたけどあまりに美しくない...ƪ(•̃͡ε•̃͡)∫
※ write 時に副作用あるので注意。
fs = require 'fs'
_ = require 'underscore'
express = require 'express'
bodyParser = require 'body-parser'
deferred = require 'deferred'
app = express()
app.use(bodyParser())
DATA_PATH = './data/'
# Routing
app.get '/', (req, res) ->
res.type('text/plain')
res.send('hello:)')
return
app.get '/api/:key', (req, res) ->
key = req.params.key
readModel(key)
.then (data) ->
if _.isNull(data)
res.send('NOT FOUND')
else
res.type('application/json')
res.json(data)
, (err) ->
res.send(err)
return
app.post '/api/:key', (req, res, next) ->
key = req.params.key
if not _.isObject(req.body) then return res.send('INVALID DATA')
readModel(key)
.then (data) ->
if _.isNull(data)
data = {}
resBody = _.extend(data, req.body)
writeModel(key, JSON.stringify(resBody))
.then (data) ->
res.type('application/json')
res.json(resBody)
, (err) ->
res.send(err)
, (err) ->
res.send(err)
return
app.delete '/api/:key/:json_key', (req, res, next) ->
key = req.params.key
jsonKey = req.params.json_key
if not _.isObject(req.body) then return res.send('INVALID DATA')
readModel(key)
.then (data) ->
if _.isNull(data) or not _.has(data, jsonKey)
res.send('NOT FOUND')
resBody = _.omit(data, jsonKey)
writeModel(key, JSON.stringify(resBody))
.then (data) ->
res.type('application/json')
res.json(resBody)
, (err) ->
res.send(err)
, (err) ->
res.send(err)
return
# I/O
readModel = (key) ->
dfd = deferred()
fileName = DATA_PATH + key + '.json'
fs.readFile fileName, 'utf8', (err, data) ->
if err
return dfd.reject('I/O ERROR')
resBody = JSON.parse(data)
return dfd.resolve(resBody)
return dfd.promise
writeModel = (key, data) ->
dfd = deferred()
fileName = DATA_PATH + key + '.json'
fs.writeFile fileName, data, 'utf8', (err) ->
if err
return dfd.reject('I/O ERROR')
return dfd.resolve(data)
return dfd.promise
app.listen(process.env.PORT or 3000)