2021/8/5 Servantのtutorialをやる
from Servant
#ログ系
これをやる
Tutorial — Servant documentation
めっちゃわかりやすいなmrsekut.icon
入れ子構造おかしくない?
https://gyazo.com/378c3e537113ffef58d94ae62c08ced4
github
同じfileに上書きしていってるので適当にcommit logを見るなど
Stackで環境構築
これを参考にする
$ stack new trial-servant-tutorial servant
$ cd trial-servant-tutorial
これをrootにコピペ
stackは追加する
nix-shellの設定などする
pythonとか要るのか?って感じするがまあいいやmrsekut.icon
$ stack build
package.yaml消した
A web API as a type
調べる
DataKinds
TypeOperators
Data.Time
GHC.TypeLits
ServantのVerb型の定義の意味を理解する
REST APIを作る基本的な型の紹介
https://docs.servant.dev/en/stable/tutorial/ApiType.html
Data.Textをimportした意味なくない?
'[JSON]って書き方はなに?
DataKindsのやつ
型を使って仕様を書き下す
code:hs
type UserAPI = "users" :> QueryParam "sortby" SortBy :> Get 'JSON User
/usersというendpoint
query parameterは?sortby=..で、AgeやName型の値を取る
GETである
[User]をJSONの型で受け取る
:>は型レベル演算子
endpointoの部分は/と読み替えればいい
e.g. "users" :> "list-all"は、users/list-allと同じ
/というendpointの場合は、type Root = Get '[JSON] [User]みたいに文字列部分を省略すればいい
:<|>で複数endpointの連結
https://docs.servant.dev/en/stable/tutorial/ApiType.html#combinators
VerbとかGetの定義場所 ref
全然わからん!mrsekut.icon
https://docs.servant.dev/en/stable/tutorial/ApiType.html#streamget-and-streampost
StreamGetとStreamPost
https://docs.servant.dev/en/stable/tutorial/ApiType.html#capture
Caputure
path parameterのことねmrsekut.icon
user/:userIdを"user" :> Caputure "userId" Integerというふうに書く
https://docs.servant.dev/en/stable/tutorial/ApiType.html#queryparam-queryparams-queryflag
複数のquery parameterなどの対応
QueryParam(既出)
/users?sortby=age
QueryParams
?param=value1&param=value2
QueryFlag
/users?active
https://docs.servant.dev/en/stable/tutorial/ApiType.html#reqbody
ReqBody
code:hs
type UserAPI7 = "users" :> ReqBody 'JSON User :> Post 'JSON User
PostでUser型のJSONを受け取る
https://docs.servant.dev/en/stable/tutorial/ApiType.html#request-headers
code:hs
type UserAPI8 = "users" :> Header "User-Agent" Text :> Get 'JSON User
request header
JSON以外のcontent typesを使う
response header
認証
空API
開発中の未完成のAPIとして仮定義するときに使うなど
waiとの対応
Serving an API ref
調べる
DeriveGeneric
FlexibleInstances
GeneralizedNewtypeDeriving
MultiParamTypeClasses
OverloadedStrings
RankNTypes
ScopedTypeVariables
Aeson
time
base-compat-batteries
bytestring
string-conversions
lucid
http-media
directory
blaze-markup
blaze-html
GHC.Generics
Proxy型
Servantmoduleはservant-serverからimportする
だからdependencyにservantを追加する必要はない
ServerというType Family
Handlerモナド
The first thing to know about the Server type ~
このへんで言ってることいまいちわからんなmrsekut.icon
全体像が見えてないからか
buildして実行して$ http :8081/usersなどでアクセスすれば見れる
お〜〜動いたmrsekut.icon
コード記述量だけで言ったらその辺のどんなserver libraryよりも簡単だな
endpointを追加する
UserAPIで列挙した順番とserver関数内の:<|>の順序は一致させないといけない
これが型システムの限界かmrsekut.icon
じっさい、順番を変にしても型エラーは出ない
頑張ればどうにかできそうな気もするけど、そこは妥協点か
https://docs.servant.dev/en/stable/tutorial/Server.html#from-combinators-to-handler-arguments
server3関数の実装にHandler型が出てくる
server3内で定義されている関数の型は、API型の定義とまんま対応してることがわかる
code:bash
$ http :8081/hello name==Alp
$ http :8081/marketing \
clientName='Alp Mestanogullari' \
clientEmail='alp@foo.com' \
clientAge:=25 \
clientInterestedIn:='"haskell","mathematics"'
https://docs.servant.dev/en/stable/tutorial/Server.html#the-fromhttpapidata-tohttpapidata-classes
Querying an API
Generating Javascript functions to query an API
Documenting an API
Authentication in Servant
あとでよむ
https://qiita.com/lotz/items/883b41fa79f060e59efa
https://logmi.jp/tech/articles/320369
https://qiita.com/algas/items/c76df85292e4e3fb83fd
https://qiita.com/sand/items/fea7c294dd7835692ff7
https://krdlab.hatenablog.com/entry/2014/12/31/170158