2

Concept

I've borrowed "mount" from the Rails world. Here's what I'm conceptually trying to do:

  • Write a mini web-app in Servant, which others can "include/mount" in larger Servant apps
  • They should be able to specify a "mount point" for URLs of this mini-app (basically a URL prefix). They should also be able to specify authentication to access this mini-app (highly recommended!)
  • Various safeLinks used within this mini-app should respect this "mount-point" (else all links would end-up being 404).

Specifics

And here are the specifics:

I've got a bunch of Servant routes in the odd-jobs library that look like this:

data Routes route = Routes
  { rFilterResults :: route :- QueryParam "filters" Filter :> Get '[HTML] (Html ())
  , rStaticAssets :: route :- "assets" :> Raw
  , rEnqueue :: route :- "enqueue" :> Capture "jobId" JobId :> Post '[HTML] NoContent
  , rRunNow :: route :- "run" :> Capture "jobId" JobId :> Post '[HTML] NoContent
  , rCancel :: route :- "cancel" :> Capture "jobId" JobId :> Post '[HTML] NoContent
  , rRefreshJobTypes :: route :- "refresh-job-types" :> Post '[HTML] NoContent
  , rRefreshJobRunners :: route :- "refresh-job-runners" :> Post '[HTML] NoContent
  } deriving (Generic)

I have a separate OddJobs.Links module that uses the RecordWildCards trick to get a bunch of safe-link generation functions in the top-level namespace:

Routes{..} = allFieldLinks' absText :: Routes (AsLink Text)

absText :: Link -> Text
absText l = "/" <> (toS $ show $ linkURI l)

The HTML generated by the job-queue's web-ui uses these top-level function as such:

form_ [ action_ (Links.rCancel jobId), method_ "post" ] $ do

Questions

  • I've been staring at safeLink, and related functions, in Servant.Links and am unable to figure out if safeLink's first argument basically figures out the "mount-point" automatically, or not? If it does, what would be the corresponding way to use fieldLink (and related functions)?
  • How do you "combine" multiple APIs, each defined with a generic-record, such that you can generate safe-link functions (and servant-clients) for the combined API?
  • Will my HTML generation functions basically need to accept the "mount-point" as an argument, generate the safe-link functions, and them pass them around everywhere? i.e. I won't be able to use the RecordWildCards trick to get these functions in the top-level namespace, right?
  • What will happen to my actual handlers, if the user of my library decides to add basic-auth while combining this mini-app into a larger servant app?
Saurabh Nanda
  • 6,373
  • 5
  • 31
  • 60
  • I can't quite put together how to parameterize the main API but this was helpful to me in solving a similar issue: https://github.com/haskell-servant/servant/issues/1040 – sdobz Mar 12 '21 at 01:55

0 Answers0