docs: readme
This commit is contained in:
68
README.md
68
README.md
@@ -5,15 +5,73 @@
|
||||
HTTP server library inspired by [`axum`](https://docs.rs/latest/axum), allowing best-in-class
|
||||
expressive routing.
|
||||
|
||||
## Example
|
||||
|
||||
This example implements this REST interface in 36LoC:
|
||||
|
||||
- `GET /cheeses` - Lists all cheeses (strings) known to server
|
||||
- `POST /cheeses` - Add a cheese to the in memory cheese list
|
||||
- `DELETE /cheeses/:cheese` - Remove a cheese from the cheese list
|
||||
|
||||
```purs
|
||||
root :: Get -> Path "/" _ -> Aff String
|
||||
root _ _ = pure "Hello, world!"
|
||||
module Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Axon as Axon
|
||||
import Axon.Request.Handler as Handler
|
||||
import Axon.Request.Parts.Class (Delete, Get, Path(..), Post)
|
||||
import Axon.Request.Parts.Path (type (/))
|
||||
import Axon.Response (Response)
|
||||
import Axon.Response.Construct (Json(..), toResponse)
|
||||
import Axon.Response.Status as Status
|
||||
import Data.Filterable (filter)
|
||||
import Data.Foldable (elem)
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Effect (Effect)
|
||||
import Effect.Aff (Aff, launchAff_, joinFiber)
|
||||
import Effect.Aff as Aff
|
||||
import Effect.Class (liftEffect)
|
||||
import Effect.Ref (Ref)
|
||||
import Effect.Ref as Ref
|
||||
|
||||
main :: Effect Unit
|
||||
main = Axon.serve (root `Handle.or` Handle.Default.notFound)
|
||||
main = launchAff_ do
|
||||
cheeses :: Ref (Array String) <- liftEffect $ Ref.new
|
||||
[ "cheddar", "swiss", "gouda" ]
|
||||
|
||||
-- GET localhost:8000/ -> 200 OK "Hello, world!"
|
||||
-- GET localhost:8000/foo -> 404 Not Found
|
||||
let
|
||||
getCheeses :: Get -> Path ("cheeses") _ -> Aff Response
|
||||
getCheeses _ _ = liftEffect do
|
||||
cheeses' <- Ref.read cheeses
|
||||
toResponse $ Status.ok /\ Json cheeses'
|
||||
|
||||
deleteCheese :: Delete -> Path ("cheeses" / String) _ -> Aff Response
|
||||
deleteCheese _ (Path id) = liftEffect do
|
||||
cheeses' <- Ref.read cheeses
|
||||
if not $ elem id cheeses' then
|
||||
toResponse Status.notFound
|
||||
else
|
||||
Ref.modify_ (filter (_ /= id)) cheeses
|
||||
*> toResponse Status.accepted
|
||||
|
||||
postCheese :: Post -> Path "cheeses" _ -> String -> Aff Response
|
||||
postCheese _ _ cheese =
|
||||
let
|
||||
tryInsert as
|
||||
| elem cheese as = { state: as, value: false }
|
||||
| otherwise = { state: as <> [ cheese ], value: true }
|
||||
in
|
||||
liftEffect
|
||||
$ Ref.modify' tryInsert cheeses
|
||||
>>= if _ then toResponse Status.accepted else toResponse Status.conflict
|
||||
|
||||
handle <-
|
||||
Axon.serveBun
|
||||
{ port: 8080, hostname: "localhost" }
|
||||
(getCheeses `Handler.or` postCheese `Handler.or` deleteCheese)
|
||||
|
||||
joinFiber handle.join
|
||||
```
|
||||
|
||||
## Request Handlers
|
||||
|
||||
@@ -29,7 +29,8 @@ main = runSpecAndExitProcess [ specReporter ] $ describe "Axon" do
|
||||
Test.Header.spec
|
||||
|
||||
pending' "example" do
|
||||
cheeses :: Ref.Ref (Array String) <- liftEffect $ Ref.new ["cheddar", "swiss", "gouda"]
|
||||
cheeses :: Ref.Ref (Array String) <- liftEffect $ Ref.new
|
||||
[ "cheddar", "swiss", "gouda" ]
|
||||
|
||||
let
|
||||
getCheeses :: Get -> Path ("cheeses") _ -> Aff Response
|
||||
@@ -50,19 +51,20 @@ main = runSpecAndExitProcess [ specReporter ] $ describe "Axon" do
|
||||
postCheese _ _ cheese =
|
||||
let
|
||||
tryInsert as
|
||||
| elem cheese as = {state: as, value: false}
|
||||
| otherwise = {state: as <> [cheese], value: true}
|
||||
| elem cheese as = { state: as, value: false }
|
||||
| otherwise = { state: as <> [ cheese ], value: true }
|
||||
in
|
||||
liftEffect
|
||||
$ Ref.modify' tryInsert cheeses
|
||||
>>= if _ then
|
||||
toResponse $ Status.accepted
|
||||
else
|
||||
toResponse $ Status.conflict
|
||||
liftEffect
|
||||
$ Ref.modify' tryInsert cheeses
|
||||
>>=
|
||||
if _ then
|
||||
toResponse $ Status.accepted
|
||||
else
|
||||
toResponse $ Status.conflict
|
||||
|
||||
handle <-
|
||||
Axon.serveBun
|
||||
{port: 8080, hostname: "localhost"}
|
||||
{ port: 8080, hostname: "localhost" }
|
||||
(getCheeses `Handler.or` postCheese `Handler.or` deleteCheese)
|
||||
|
||||
Aff.joinFiber $ handle.join
|
||||
|
||||
Reference in New Issue
Block a user