軽量HaskellウェブフレームワークServant
軽量で型安全なウェブフレームワーク Servant
Servantプロジェクト作成
$ stack new projname servant
ビルド
$ stack build
実行
http://localhost:8080/users でJSONの出力が確認できる
$ stack build
ルーティング
URLのルーティングは API型で定義する、 DataKind拡張などを利用して型に変換する /users というURLの定義は以下のように書くMethod は GET で レスポンスは JSON形式の User配列という意味
type API = "users" :> Get '[JSON] [User]
...
/userid/[数値] などパラメータを取得したい場合、 Capture を利用する
:<|> "userid" :> Capture "i" Int :> Get '[JSON] (Maybe User)
/search?username=[文字列] のようなクエリパラメータを利用する場合は QueryParam を利用する
:<|> "search" :> QueryParam "username" String :> Get '[JSON] [User]
Method の POST の利用方法で入力のリクエストにJSON形式のパラメータ ModInfo 型をしていする場合は以下のとおり
:<|> "usermod" :> ReqBody '[JSON] ModInfo :> Post '[JSON] [User]
:<|> でURLを複数並べる
type API = "users" :> Get '[JSON] [User]
:<|> "userage" :> Capture "p" Int :> Get '[JSON] [User]
:<|> "userid" :> Capture "i" Int :> Get '[JSON] (Maybe User)
:<|> "search" :> QueryParam "username" String :> Get '[JSON] [User]
:<|> "usermod" :> ReqBody '[JSON] ModInfo :> Post '[JSON] [User]
パラメータ
パラメータやレスポンスの値をJSON化したい場合は、Jsonクラスのインスタンスとするために $(deriveJSON defaultOptions ’’ModInfo) を書く
...
data ModInfo = ModInfo
{ modId :: Int
, modAge :: Int
, modFirstName :: String
, modLastName :: String
} deriving (Eq, Show)
$(deriveJSON defaultOptions ''ModInfo)
...
こうすることで、Haskellが型をJSON化してくれる
Handler
別の世界ではコントローラーと呼ぶレイヤーだと思ってる、しらんけど、Handlerの型情報
newtype Handler a = ExceptT ServerError IO a -> Handler a
で定義されている、ExceptTは
newtype ExceptT e m a = ExceptT (m (Either e a))
ServantのHandlerはIOモナド内で結果aかエラーのeを返すすごくシンプルな関数定義となっている、そして ServerError は
type ServerError :: *
data ServerError
= ServerError { errHTTPCode :: Int
, errReasonPhrase :: String
, errBody :: Data.ByteString.Lazy.Internal.ByteString
, errHeaders :: [Network.HTTP.Types.Header.Header]
}
-- Defined in ‘Servant.Server.Internal.ServerError’
instance Eq ServerError
-- Defined in ‘Servant.Server.Internal.ServerError’
instance Show ServerError
-- Defined in ‘Servant.Server.Internal.ServerError’
instance Read ServerError
-- Defined in ‘Servant.Server.Internal.ServerError’
エラーコードなどが定義されている
コード
JSON形式しか返却できませんが、サンプルはgithubです、利用方法は README.md を参照してください
https://github.com/calimakvo/svty
やはり厳格な型システムのおかげで軽量でも安全に作れるところが素晴らしいと思います
参考資料
たしか、Haskell Day 2018の勉強会のこのお話がきっかけでServant知りました、良い資料ですご一読ください
Haskell × Servantで作る、安全かつ高速なAPI開発
Posted on 2023-02-12 16:21:37