haskell-servant / haskell-servant/servant

Question on nested API (tutorial)

Open
#1,320 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
2k
Forks
427
Avg merge
2d 23h
Merged PRs (30d)
5

Description

I've been going through the tutorial and found the following confusing in
https://docs.servant.dev/en/stable/tutorial/Server.html#nested-apis.

```
-- notice how getUser and deleteUser
-- have a different type! no argument anymore,
-- the argument directly goes to the whole Server
server9 :: Server UserAPI4
server9 userid = getUser userid :<|> deleteUser userid

where getUser :: Int -> Handler User
getUser = error "..."

deleteUser :: Int -> Handler NoContent
deleteUser = error "..."
```
It compiles, but the way it is implemented feels like it defeats the purpose of the nested APIs, and moreover does not seem to match the text surrounding it. In my understanding, I was expecting:
```
-- notice how getUser and deleteUser
-- have a different type! no argument anymore,
-- the argument directly goes to the whole Server
server9 :: Server UserAPI4
server9 userid = getUser :<|> deleteUser

where getUser :: Handler User
getUser = error "..."

deleteUser :: Handler NoContent
deleteUser = error "..."
```

However, later on it is done in a similar fashion
```
type UsersAPI =
Get '[JSON] [User] -- list users
:<|> ReqBody '[JSON] User :> PostNoContent -- add a user
:<|> Capture "userid" Int :>
( Get '[JSON] User -- view a user
:<|> ReqBody '[JSON] User :> PutNoContent -- update a user
:<|> DeleteNoContent -- delete a user
)

usersServer :: Server UsersAPI
usersServer = getUsers :<|> newUser :<|> userOperations

where getUsers :: Handler [User]
getUsers = error "..."

newUser :: User -> Handler NoContent
newUser = error "..."

userOperations userid =
viewUser userid :<|> updateUser userid :<|> deleteUser userid

where
viewUser :: Int -> Handler User
viewUser = error "..."

updateUser :: Int -> User -> Handler NoContent
updateUser = error "..."

deleteUser :: Int -> Handler NoContent
deleteUser = error "..."
```
vs just
```
userOperations userid =
viewUser :<|> updateUser :<|> deleteUser

where
viewUser :: Handler User
viewUser = error "..."

updateUser :: User -> Handler NoContent
updateUser = error "..."

deleteUser :: Handler NoContent
deleteUser = error "..."
```
So now I am not sure whether I might be misunderstanding something about this.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.