Home > Software engineering >  Haskell servant combined api implementation
Haskell servant combined api implementation

Time:09-08

I am going through the servant tutorial found here. There is a partial implementation that is left for the user to figure out what it should be.

type APIFor a i =
       Get '[JSON] [a]
  :<|> ReqBody '[JSON] a :> PostNoContent
  :<|> Capture "id" i :>
         ( Get '[JSON] a
      :<|> ReqBody '[JSON] a :> PutNoContent
      :<|> DeleteNoContent
         )

serverFor :: Handler [a]
          -> (a -> Handler NoContent)
          -> (i -> Handler a)
          -> (i -> a -> Handler NoContent)
          -> (i -> Handler NoContent)
          -> Server (APIFor a i)
serverFor = error "..." -- What should be here?

Following from the previous examples I came up with the implementation:

serverFor = listing :<|> ops

    where
        listing :: Handler [a]
        listing = error ""

        ops a i =
            creating a
            :<|> getById i
            :<|> updating i a
            :<|> deleting i

            where
                creating :: a -> Handler NoContent
                creating a = error ""

                getById :: i -> Handler a
                getById id = error ""

                updating :: i -> a -> Handler NoContent
                updating i a = error ""

                deleting :: i -> Handler NoContent
                deleting i = error ""

But am getting the error:

• Couldn't match expected type ‘Handler [a]
                                -> (a -> Handler NoContent)
                                -> (i -> Handler a)
                                -> (i -> a -> Handler NoContent)
                                -> (i -> Handler NoContent)
                                -> Server (APIFor a i)’
              with actual type ‘Handler [a0]
                                :<|> (a1
                                      -> i0
                                      -> Handler NoContent
                                         :<|> (Handler a2
                                               :<|> (Handler NoContent :<|> Handler NoContent)))’
• Possible cause: ‘(:<|>)’ is applied to too many arguments
  In the expression: listing :<|> ops

I understand what the error is saying but do not know how to implement it correctly. Is anyone able to help with what the correct implementation should be?

CodePudding user response:

The signature of the serverFor function says it takes handler functions and builds the Server.

serverFor list create get update delete = 
  -- combine handlers according to API type
  list :<|> create :<|> (\i -> get i :<|> update i :<|> delete i)

you can then call serverFor for your specific types.

data User = User {id :: Int}

server :: Server (APIFor User Int)
server = serverFor listing creating getById updating deleting
  where
    listing :: Handler [User]
    listing = error ""
    creating :: User -> Handler NoContent
    creating a = error ""
    getById :: Int -> Handler User
    getById id = error ""
    updating :: Int -> User -> Handler NoContent
    updating i a = error ""
    deleting :: Int -> Handler NoContent
    deleting i = error ""

CodePudding user response:

• Couldn't match type ‘()’
                     with ‘Scripts.DatumType a0
                           -> Scripts.RedeemerType a0 -> ScriptContext -> Bool’
      Expected type: template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.Q
                       (template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.TExp
                          (PlutusTx.CompiledCode
                             (Scripts.ValidatorType a0 -> Scripts.WrappedValidatorType)))
        Actual type: template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.Q
                       (template-haskell-2.16.0.0:Language.Haskell.TH.Syntax.TExp
                          (PlutusTx.CompiledCode
                             (() -> MyRedeemer -> ScriptContext -> Bool)))
    • In the expression: PlutusTx.compile [|| mkValidator ||]
      In the Template Haskell splice
        $$(PlutusTx.compile [|| mkValidator ||])
      In the second argument of ‘Scripts.mkTypedValidator’, namely
        ‘$$(PlutusTx.compile [|| mkValidator ||])’
   |
56 |     $$(PlutusTx.compile [|| mkValidator ||])
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  • Related