okapi/README.md
2023-11-14 08:19:59 -08:00

90 lines
2.3 KiB
Markdown

# 🦓🦒Okapi
Okapi is a data-driven micro framework for implementing HTTP servers.
- Ergonomic DSLs for routing and parsing requests
- Integrate Okapi with ANY monad stack or effect system
- Automatically generate clients and OpenAPI specifications (coming soon)
- Programatically generate your API's structure
## Hello World Example
```haskell
helloWorld =
responder @200 @'[] @Text.Text @Text.Text
. method HTTP.GET id
$ \greet _req -> return $ greet noHeaders "Hello World!"
main =
Warp.run 8000
. withDefault helloWorld
$ \_ resp -> resp $ Wai.responseLBS HTTP.status404 [] "Not Found..."
```
## Calculator Example
```haskell
data Operator
= Add
| Sub
| Mul
| Div
| Sq
| Neg
deriving (Show)
instance Web.FromHttpApiData Operator where
parseUrlPiece "add" = Right Add
parseUrlPiece "sub" = Right Sub
parseUrlPiece "minus" = Right Sub
parseUrlPiece "mul" = Right Mul
parseUrlPiece "div" = Right Div
parseUrlPiece "neg" = Right Neg
parseUrlPiece "sq" = Right Sq
parseUrlPiece "square" = Right Sq
parseUrlPiece _ = Left "Can't parse operator..."
shared =
lit "calc"
. param @Operator
. param @Int
unary =
responder @200 @'[] @Text.Text @Int
. responder @500 @'[] @Text.Text @Text.Text
. method HTTP.GET id
unaryHandler operator x ok wrongArgs _req =
return $ case operator of
Sq -> ok noHeaders (x * x)
Neg -> ok noHeaders (x * (-1))
_ -> wrongArgs noHeaders $ Text.pack (show operator) <> " needs two arguments."
binary =
param @Int
. responder @200 @'[] @Text.Text @Int
. responder @500 @'[] @Text.Text @Text.Text
. responder @403 @'[] @Text.Text @Text.Text
. method HTTP.GET id
binaryHandler operator x y ok wrongArgs divByZeroErr _req =
return $ case operator of
Add -> ok noHeaders (x + y)
Sub -> ok noHeaders (x - y)
Mul -> ok noHeaders (x * y)
Div ->
if y == 0
then divByZeroErr noHeaders "You can't divide by 0."
else ok noHeaders (div x y)
_ -> wrongArgs noHeaders $ Text.pack (show operator) <> " needs one argument."
calc = shared $ choice
[ unary unaryHandler
, binary binaryHandler
]
main =
Warp.run 8003
. withDefault calc
$ \_ resp -> resp $ Wai.responseLBS HTTP.status404 [] "Not Found..."
```