haskell-servant / servant-elm

Automatically derive Elm functions to query servant webservices
BSD 3-Clause "New" or "Revised" License
164 stars 48 forks source link

NoContent is not translated to an Elm type #27

Closed mradke closed 7 years ago

mradke commented 7 years ago

Currently I am trying to port haskell-servant/example-servant-elm to Elm 0.18 and hence updated the used resolver to lts-8.0 the version of elm-export to commit 94b939b and the version of servant-elm to 301179e which went exceptionally well.

Unfortunately I am now stuck with a little API issue:

type Api =
  "api" :>
    ("item" :> Get '[JSON] [ItemId] :<|>
     "item" :> Capture "itemId" ItemId :> Get '[JSON] Item :<|>
     "item" :> ReqBody '[JSON] String :> Post '[JSON] ItemId :<|>
     "item" :> Capture "itemId" ItemId :> Delete '[JSON] NoContent)

The NoContent return type will result in a NoContent type in the generated api file which is not what I expect (since NoContent is unspecified on the elm side).

In the ElmOptions which get passed to generateElmForAPIWith I also specified explicitly

emptyResponseElmTypes =
      [ Elm.toElmType NoContent
      , Elm.toElmType ()
      ]

Additionally I tried toElmTypeSource (Proxy :: Proxy NoContent) without any effect. So how do I get the NoContent type translated into a known elm value?

P. s. since I fear to misunderstand servant-elm at this point I thought this would be the appropriate place to ask. If this is not the case, it would be nice if you could point me into the right direction. Thanks!

mattjbray commented 7 years ago

Hi @mradke,

You should be on the right lines with toElmTypeSource (Proxy :: Proxy NoContent).

The examples/e2e-tests example makes use of NoContent - have a look at generate.hs, and the generated type and HTTP request.

You shouldn't need to set emptyResponseElmTypes as this is the default. This option simply determines the return types for which we generate a request that expects an empty string body, rather than a decodable JSON value. You'll see in the example that the NoContent request expects an empty string body, whereas the other requests expect JSON bodies. (An empty string is not valid JSON.)

mattjbray commented 7 years ago

Note that this changed a few months ago: you now have to explicitly generate types/encoders/decoders for all of the data types used by your API.

Previously, I was maintaining a fork of elm-export that did this automatically, but it was buggy so I decided to remove it. Hopefully we'll get it back in upstream elm-export one day.

mradke commented 7 years ago

Hey thanks for the quick response! You are absolutely right that toElmTypeSource (Proxy :: Proxy NoContent) is indeed working correctly. I was confused, because I misread the output:

-- What I thought it was
type alias NoContent = NoContent

-- What it actually is
type NoContent = NoContent

TL;DR; it did not occur to me, that NoContent is defined as a union type with only one value...

Thanks again for your help and all the work you've put into this library! 👍