Skip to content

A library to easily use servant and GDP together to build web apis with a lot of knowledge in the types

License

Notifications You must be signed in to change notification settings

mtonnberg/servant-gdp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Servant ❤️ GDP

In a nutshell

To get more productive, produce high-quality web APIs and reduce the number of needed tests we can combine Servant (A web api framework) and GDP (Ghosts of Departed Proofs). This allows for quite expressive API declarations which leads to more knowledge captured. See a full example.

-- http://localhost/div/10/5 would return 2
type DivWebApi numerator denominator =
  "div"
    :> CaptureNamed (Int ~~ numerator 
                    ::: IsPositive numerator)
    :> CaptureNamed (Int ~~ denominator
                    ::: IsPositive denominator)
    :> Get
         '[JSON]
         ( Int ? IsEqualOrLessThan numerator
         )

or

-- http://localhost/habitats/savanna/animals/3
-- could return ["lion", "elephant"]
type GetAnimalsForHabitat user habitat pagesize =
  AuthProtect "normalUser"
    :> "habitats"
    :> CaptureNamed (String ~~ habitat ::: IsNonEmpty habitat && IsTrimmed habitat)
    :> "animals"
    :> CaptureNamed (Int ~~ pagesize ::: IsPositive pagesize)
    :> Get
         '[JSON]
         ( ( [String ? IsAValidatedAnimal habitat] ? HasAMaximumLengthOf pagesize
           )
             ::: user `HasAccessToHabitat` habitat
         )

See https://github.com/mtonnberg/gdp-demo for a full, working example.

How does it work

API-input is captured as named variables, making the named contexts span the entire request. This in turn, makes it possible to express a lot of domain knowledge/requirements in the Servant API type.

Why does this exist?

To both make the API-capabilities clearer and to make it easier to implement.

It is often quite easy to identify domain rules, invariants and preconditions for the API but hard to capture that knowledge in the types. Instead a lot of domain rules and requirements are hidden in the implementation logic.

Moving information to the types are in line with Knowledge-as-Code, read more about the benefits here: Knowledge-as-Code

About

A library to easily use servant and GDP together to build web apis with a lot of knowledge in the types

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages