概要
HTTP で JSON を POST すると、JSON で応答を返すシンプルなサーバーを Go言語で作ってみたものです。
日本語文章を POST すると mecab でパースして、結果を返してくれます。
関連記事
インターフェース
リクエスト
HTTP で JSON形式のコマンドを POST します。
{"Token": "01234", "Sentence": "なにか文章"}
- Token: future reserve
- Sentence: mecab で解析したい一文(UTF-8)
リザルト
JSON形式で戻ってきます。
{"Status":0,"Code":"OK","Result":["A","B","C"]}
- Status: 0 で成功、それ以外で失敗
- Code: 成功時は OK、それ以外は失敗理由
- Result: 成功時 mecab の解析結果が array で戻る(UTF-8)
インストール
go install bitbucket.org/rerofumi/webmecab
でどぞー
実行
install で入れたのならば $GOPATH/bin に webmecab が居るはず。
usage: webmecab [-p port]
- p もしくは port でポート指定、無指定時 80
ソースコード
mecab-web-api.go
package main
import (
"bitbucket.org/rerofumi/mecab"
"fmt"
"net/http"
"encoding/json"
"os"
"flag"
"strconv"
"io"
"bufio"
)
/* --- JSON define */
type MecabOutput struct {
Status int
Code string
Result []string
}
type MecabInput struct {
Token string
Sentence string
}
/* ----------------------- */
/* --- controller */
/* ----------------------- */
func apiRequest(w http.ResponseWriter, r *http.Request) {
list := make([]string,0)
ret := MecabOutput{0,"OK",list}
request := ""
// JSON return
defer func() {
// result
outjson,err := json.Marshal(ret)
if err != nil {
fmt.Println(err) //TODO: change to log
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, string(outjson))
}()
// type check
if r.Method != "POST" {
ret.Status = 1
ret.Code = "Not POST method"
return
}
// request body
rb := bufio.NewReader(r.Body)
for {
s, err := rb.ReadString('\n')
request = request + s
if err == io.EOF { break }
}
// JSON parse
var dec MecabInput
b := []byte(request)
err := json.Unmarshal(b, &dec)
if err != nil {
ret.Status = 2
ret.Code = "JSON parse error."
return
}
// mecab parse
result, err := mecab.Parse(dec.Sentence)
if err == nil {
for _, n := range result {
ret.Result = append(ret.Result, n)
}
}
}
/* ----------------------- */
/* --- main */
/* ----------------------- */
func main() {
// switch
var (portNum int)
flag.IntVar(&portNum, "port", 80, "int flag")
flag.IntVar(&portNum, "p", 80, "int flag")
flag.Parse()
var port string
port = ":"+strconv.Itoa(portNum)
fmt.Println("listen port =", port)
// route handler
http.HandleFunc("/", apiRequest)
// do serve
err := http.ListenAndServe(port, nil)
// error abort
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}