Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookbooks #1542

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ packages:
doc/cookbook/db-sqlite-simple
doc/cookbook/file-upload
doc/cookbook/generic
doc/cookbook/namedRoutes
doc/cookbook/hoist-server-with-context
doc/cookbook/https
doc/cookbook/jwt-and-basic-auth
Expand Down
26 changes: 17 additions & 9 deletions doc/cookbook/generic/Generic.lhs
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# Using generics
# Record-based APIs: the simple case

This cookbook explains how to implement an API with a simple record-based
structure. We only deal with non-nested APIs in which every endpoint is on the same
level.

If a you need nesting because you have different branches in your API tree, you
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If a" => "If"

might want to jump directly to the [Record-based APIs: the nested records
case](../namedRoutes/NamedRoutes.html) cookbook that broaches the subject.

Shall we begin?

```haskell
{-# LANGUAGE DataKinds #-}
Expand All @@ -22,12 +32,12 @@ import Servant.Server.Generic
```

The usage is simple, if you only need a collection of routes.
First you define a record with field types prefixed by a parameter `route`:
First you define a record with field types prefixed by a parameter `mode`:

```haskell
data Routes route = Routes
{ _get :: route :- Capture "id" Int :> Get '[JSON] String
, _put :: route :- ReqBody '[JSON] Int :> Put '[JSON] Bool
data Routes mode = Routes
{ _get :: mode :- Capture "id" Int :> Get '[JSON] String
, _put :: mode :- ReqBody '[JSON] Int :> Put '[JSON] Bool
}
deriving (Generic)
```
Expand Down Expand Up @@ -110,7 +120,7 @@ main = do
_ -> putStrLn "To run, pass 'run' argument: cabal new-run cookbook-generic run"
```

## Using generics together with a custom monad
## Using record-based APIs together with a custom monad

If your app uses a custom monad, here's how you can combine it with
generics.
Expand All @@ -121,9 +131,6 @@ data AppCustomState =

type AppM = ReaderT AppCustomState Handler

apiMyMonad :: Proxy (ToServantApi Routes)
apiMyMonad = genericApi (Proxy :: Proxy Routes)

getRouteMyMonad :: Int -> AppM String
getRouteMyMonad = return . show

Expand All @@ -139,3 +146,4 @@ nt s x = runReaderT x s

appMyMonad :: AppCustomState -> Application
appMyMonad state = genericServeT (nt state) recordMyMonad
```
1 change: 1 addition & 0 deletions doc/cookbook/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ you name it!

structuring-apis/StructuringApis.lhs
generic/Generic.lhs
namedRoutes/NamedRoutes.lhs
https/Https.lhs
db-mysql-basics/MysqlBasics.lhs
db-sqlite-simple/DBConnection.lhs
Expand Down
Loading