haskell-servant / haskell-servant/servant

Monadic form validation with digestive functors.

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

Description

Hi,

So, I'm trying to validate a form on my application with digestive functors but I can't find a good way to successfully do that.

I've read #236 but I can't find `FromFormUrlEncoded` class. Was it removed? If so, what is the alternative?

I have a `Credentials` data type that carries username and password. It should be validated to make sure password is strong enough and username is not empty, and it should also check if user with that username already exists.

I've made a simple wrapper type called 'Page' that contains some meta data about the page that is being rendered and the main content of the page.

```
data Meta = Meta
{ title :: Text
} deriving ( Show, Generic )

data Page content = Page
{ meta :: Meta
, content :: content
} deriving ( Show, Generic )
```

And I have a `Credentials` type with the accompanying form.

```
data Credentials = Credentials
{ username :: Text
, password :: Text
} deriving ( Show, Generic )

credentialsForm :: Monad m => Form Html m Credentials
credentialsForm = Credentials
<$> "username" .: checkIfUserExistsInDB
<*> "password" .: nonEmptyText
where
checkIfUserExistsInDB = undefined
nonEmptyText = check "Can't be empty!" (not . null) $ text Nothing

credentialsFormView :: View Html -> Html
credentialsFormView v = form v "/user/new" $ do
div_ $ do
label "username" v "Username"
inputText "username" v
div_ $ do
label "password" v "Password"
inputPassword "password" v
div_ $ do
inputSubmit "Register"
```

Idea is to have something like this:
```
...
:<|> "user" :> "new" :> Get '[HTML] Page (GetForm Credentials)
:<|> "user" :> "new" :> ReqBody '[FormUrlEncoded] Credentials :>
(Post '[HTML] (Page (BadForm User)) :<|> (Post '[HTML] (Page (GoodForm User))
...
```

where user first gets the empty form, and than it can do a post request to the server where input data is validated (within a custom monad if possible) and than result is either a `GoodForm` which than inserts a new user into the database and returns a success page, or a `BadForm` which renders HTML with form containing error warnings.

I haven't really seen many (or any) tutorials about form validation in servant which seems like a very important thing, so I'm a bit overwhelmed with this task.

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.