JuliaでWebAPIサーバの作り方を勉強しているので、備忘録も兼ねて書き連ねていきます。
HTTP.jlを使うと簡単にWebサーバを建てることができます。 Genie.jlというJulia製のWebフレームワークがありますが、今回は使用しません。 なお、Genie.jlもHTTP.jlをベースに書かれているそうです。
まずは、インデックスルート"/"に対する簡単なHTTPサーバ構成を示します。
using HTTP # ルータを用意 const ROUTER = HTTP.Router() # ハンドラーを定義 function index(req::HTTP.Request) @show req return HTTP.Response(200, ["Content-Type" => "text/plain"], "hello, world") end # ルータにハンドラを登録する HTTP.register!(ROUTER, "GET", "/", index) # ローカルアドレス address = Sockets.localhost # ポート番号 port = 8080 # HTTPサーバ起動 HTTP.serve(ROUTER, address, port)
http://localhost:8080/
にアクセスするとhello, world
が返ってきます。ctrl + c
で停止できます。
上記の例ではインデックスパス"/"に対してGETメソッドを受けたときのハンドラとしてindex関数を登録しています。
ハンドラ関数には引数HTTP.Request
型を取る関数で、戻り値にはHTTP.Response
型を返します。
こんな感じで、HTTP.jlを使うと簡単にWebサーバを建てることができます。
続いてこれをリクエストボディにJSONを返すAPIに書き換えていきます。
using JSON3 # indexを書き換える function index(req::HTTP.Request) body = Dict{Symbol,String}(:message => "hello, world") # ヘッダーにJSONを返すことを示す headers = ["Content-Type" => "application/json"] return HTTP.Response(200, headers, JSON3.write(body)) end # 再登録 HTTP.register!(ROUTER, "GET", "/", index) # 再起動 HTTP.serve(ROUTER, address, port)
これで、http://localhost:8080/
にアクセスすると{"message": "hello, world"}
というJSONを返すようになります。
まず、JSON3パッケージを使うとJuliaのオブジェクトをJSONにシリアライズすることができます。
# Julia -> JSON文字列 json = JSON3.write(Dict(:message => "message", :data => "data")) # JSON文字列からJuliaオブジェクト JSON3.read(json) println(json.message) println(json.data)
おまけ
ここで、JSON3.read
が返すオブジェクトは汎用的なオブジェクトで、Juliaのユーザ定義型(構造体)にデシリアライズするためにはStructTypes.jl
というパッケージを使うと実現できます。※Juliaの構造体に明示的にparseすることで、エラーチェックなどもついでに行うことができます。
using StructTypes # ユーザ型を定義 struct RequestBody name::String email::String end # StructTypeに型を登録する StructTypes.StructType(::Type{RequestBody}) = StructTypes.Struct() body = """{ "name": "taro", "email": "taro@example.com" }""" obj = JSON3.read(body, RequestBody) println(obj) # RequestBody("taro", "taro@example.com")