HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Moduleyesod-core-1.7.0.0Haskell2010

Yesod.Core.Dispatch

  • 5 types
  • 4 classes
  • 39 values

Quasi-quoted routing

7 declarations
valuemkYesod
  1. :: String

    name of the argument datatype

  2. -> [ResourceTree String]
  3. -> Q [Dec]
#

Generates URL datatype and site function for the given Resources. This is used for creating sites, not subsites. See mkYesodSubData and mkYesodSubDispatch for the latter. Use parseRoutes to create the Resources.

Contexts and type variables in the name of the datatype are parsed. For example, a datatype App a with typeclass constraint MyClass a can be written as "(MyClass a) => App a".

More fine-grained

valuemkYesodData :: String -> [ResourceTree String] -> Q [Dec]
#

Sometimes, you will want to declare your routes in one file and define your handlers elsewhere. For example, this is the only way to break up a monolithic file into smaller parts. Use this function, paired with mkYesodDispatch, to do just that.

valuemkYesodSubDispatchInstance
  1. :: String

    Foundation type with optional context, e.g. "(MyClass a) => MySub a"

  2. -> [ResourceTree String]

    Resources (e.g. resourcesMySub)

  3. -> Q [Dec]
#

Generate both YesodSubDispatch and YesodSubDispatchNested instances for a parameterized subsite. This is the subsite equivalent of using mkYesod for top-level sites.

Usage:

mkYesodSubDispatchInstance "(MyClass a) => MySub a" resourcesMySub

This generates:

  1. A YesodSubDispatch instance using mkYesodSubDispatch

  2. YesodSubDispatchNested instances for any nested route fragments

The generated instances quantify over the master site and constrain it only through the subsite's own class. For a parameterized subsite this normally means the subsite's class carries a subsite -> master functional dependency (so master is determined) and the using module enables UndecidableInstances (the instance contexts mention type-family applications and non-variable arguments), along with FlexibleContexts, FlexibleInstances, MultiParamTypeClasses and TypeFamilies. The nested route datatype must also declare exactly as many type parameters as the subsite has type arguments (see the arity note below).

valuemkYesodSubDispatchInstanceOpts
  1. :: RouteOpts
  2. -> String

    Foundation type with optional context, e.g. "(MyClass a) => MySub a"

  3. -> [ResourceTree String]

    Resources (e.g. resourcesMySub)

  4. -> Q [Dec]
#

Like mkYesodSubDispatchInstance, but takes a RouteOpts so a subsite can control nested-route generation — most usefully setNestedRouteFallthrough (which mkYesodSubDispatchInstance leaves at its default of False). The flag is threaded into both the yesodSubDispatch body (so the subsite's own top-level parent clauses fall through to later siblings on an inner miss) and the generated YesodSubDispatchNested fragment instances.

Splitting a subsite's nested routes across modules

These re-exports let a separately-compiled module generate a subsite's YesodSubDispatchNested instance by hand (see the subsite-route-splitting recipe in docs/split-route-compilation.md). mkNestedSubDispatchInstance takes the resources as [ResourceTree String] (the parseRoutes quasi-quoter's output) and parses them internally, so no manual type-parsing is needed.

valuemkNestedSubDispatchInstance
  1. :: RouteOpts
  2. -> String

    target nested route name

  3. -> Cxt

    instance context

  4. -> TyArgs

    type arguments

  5. -> (Exp -> Q Exp)

    unwrapper

  6. -> [ResourceTree String]

    all resources (as parsed from source)

  7. -> Q [Dec]
#

Generate a YesodSubDispatchNested instance for a nested route within a subsite, for hand-written split-route modules (see the subsite-splitting recipe in docs/split-route-compilation.md).

Takes the resources as [ResourceTree String] — exactly the form the parseRoutes quasi-quoter produces — and parses them to Type internally via parseResourceTypes, so the caller never touches the partial parseType/dropBracket. A malformed type fails the splice with an attributed error instead.

datadata TyArgs
#

The type arguments of a route datatype, paired with the source Name each was derived from. A monomorphic site like App has NoTyArgs; a parameterized one like MySub subsite has SomeTyArgs.

Carrying the (non-)emptiness in the type — rather than as a bare list with a separate null check — keeps "are there type args?" and "what are they?" a single fact, so the populated branch hands you the NonEmpty directly.

Instances2Eq, Show
  • Eq TyArgsDefined in yesod-core-1.7.0.0 · Yesod.Routes.TH.Types
  • Show TyArgsDefined in yesod-core-1.7.0.0 · Yesod.Routes.TH.Types

Route generation options

datadata RouteOpts
#

General opts data type for generating yesod.

Contains options for customizing code generation for the router in mkYesodData, including what type class instances will be derived for the route datatype, whether to parameterize subroutes, and whether or not to create the resources :: [ResourceTree String] value. Use the setting functions on defaultOpts to set specific fields.

valuedefaultOpts :: RouteOpts
#

Default options for generating routes.

The defaults are:

Use the set* functions to override individual fields.

Determine whether or not to generate the resourcesApp value.

Disabling this can be useful if you are creating the routes :: [ResourceTree String] elsewhere in your module, and referring to it here. The resourcesApp can become very large in large applications, and duplicating it can result in signifiacntly higher compile times.

Default: True.

If you set this with routeName, then the code generation will generate code for the routeName to be imported in the main dispatch class. This allows you to generate code in separate modules.

Example:

First, you would put your route definitions into their own file.

module App.Routes.Resources where

import Yesod.Core

appResources :: [ResourceTree String]
appResources = [parseRoutes|
    /  HomeR GET

    /nest NestR:
        /     NestIndexR GET POST
        /#Int NestShowR  GET POST

|]

We have defined a nested route called NestR here. A nested route is created with the : after the route name.

Then, in a module for the route specifically, we can generate the route datatype and instances for later hooking in to the main instance.

module App.Routes.NestR where

import App.Routes.Resources
import Yesod.Core

mkYesodOpts (setFocusOnNestedRoute NestR defaultOpts) App appResources

If you only want to generate the datatypes, you can separate things further using mkYesodDataOpts and mkYesodDispatchOpts.

Finally, import that type into your main yesod macro code.

module App where

import App.Routes.Resources (appResources)
import App.Routes.NestR (NestR(..))

mkYesod App appResources

The call to mkYesod will delegate to the generated code for NestR rather than regenerating it.

By default, defaultOpts starts unfocused (the whole route tree is generated). Use unsetFocusOnNestedRoute to clear a previously-set focus.

For a full walkthrough — including subsites, linking to nested routes, and why split sites should enable setNestedRouteFallthrough — see the guide at https://github.com/yesodweb/yesod/blob/master/yesod-core/docs/split-route-compilation.md.

If True, generate nested-discovery code (separate subroute datatypes and RenderRouteNested dispatch instances) for a parameterized/ site instead of the backwards-compatible inline output. The subroute datatypes then carry the parent site's type variables so that the ParentSite / ParentArgs associated types stay well-scoped.

Because the generated nested instances are parameterized over the site's type variables, the splice emits instance heads with non-variable arguments; a module using this typically needs FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeFamilies and, for a parameterized subsite whose master is determined by the subsite (a subsite -> master functional dependency on the user's class), UndecidableInstances.

Monomorphic sites always use nested discovery regardless of this flag; see discoveryMode.

Default: False.

Helpers

valuedefaultGen :: IO Int
#

Generate a random number uniformly distributed in the full range of Int.

Note: Before 1.6.20, this generates pseudo-random number in an unspecified range. The range size may not be a power of 2. Since 1.6.20, this uses a secure entropy source and generates in the full range of Int.

Path pieces

classclass PathPiece s where
#

Methods

Instances18PathPiece, …

Convert to WAI

12 declarations
valuetoWaiApp :: YesodDispatch site => site -> IO Application
#

Same as toWaiAppPlain, but provides a default set of middlewares. This set may change with future releases, but currently covers:

  • Logging

  • GZIP compression

  • Automatic HEAD method handling

  • Request method override with the _method query string parameter

  • Accept header override with the _accept query string parameter

valuetoWaiAppPlain :: YesodDispatch site => site -> IO Application
#

Convert the given argument into a WAI application, executable with any WAI handler. This function will provide no middlewares; if you want commonly used middlewares, please use toWaiApp.

classclass RedirectUrl site url => UrlToDispatch url site where
#

Build a WAI Application for site, indexed by a url type that can be rendered to a route of site (via RedirectUrl).

Note that dispatch is purely path-based: the hand-written instances below discard the url value (urlToDispatch _ = yesodDispatch) and route on the request's pathInfo. The url argument exists only to select the instance and to carry the RedirectUrl constraint — it is not consulted at runtime.

This is equivalent to YesodDispatch but allows us to vary on the url type, which lets us demand additional constraints in test contexts.

Methods

Instances5UrlToDispatch
valuemkYesodRunnerEnv :: Yesod site => site -> IO (YesodRunnerEnv site)
#

Construct a YesodRunnerEnv for a site, initializing its logger, session backend, and other runtime state. This is the environment threaded through dispatch; toWaiAppPlain and friends build one for you, but it is exposed so callers can construct and reuse a runner environment directly.

valuetoWaiAppPlainNested
  1. :: (site ~ ParentSite route, Yesod site, YesodDispatchNested route, ToParentRoute route)
  2. => Proxy route
  3. -> ParentArgs route
  4. -> site
  5. -> IO Application
#

Convert the given argument into a WAI application, executable with any WAI handler. This function will provide no middlewares; if you want commonly used middlewares, please use toWaiApp.

This function allows you to create an Application that only responds to a subset of the site routes. This is really only useful for writing tests, but it does allow you to write tests that only depend on a subset of the handlers instead of all handlers.

valuewarp :: YesodDispatch site => Int -> site -> IO ()
#

A convenience method to run an application using the Warp webserver on the specified port. Automatically calls toWaiApp. Provides a default set of middlewares. This set may change at any point without a breaking version number. Currently, it includes:

  • Logging

  • GZIP compression

  • Automatic HEAD method handling

  • Request method override with the _method query string parameter

  • Accept header override with the _accept query string parameter

If you need more fine-grained control of middlewares, please use toWaiApp directly.

Since 1.2.0

valuewarpEnv :: YesodDispatch site => site -> IO ()
#

Runs your application using default middlewares (i.e., via toWaiApp). It reads port information from the PORT environment variable, as used by tools such as Keter and the FP Complete School of Haskell.

Note that the exact behavior of this function may be modified slightly over time to work correctly with external tools, without a change to the type signature.

Subsite nested dispatch

1 declaration
classclass RenderRouteNested a => YesodSubDispatchNested a where
#

Like YesodDispatchNested, but for subsites. This class enables class-based delegation for nested routes within subsites, allowing module separation and symmetry with YesodDispatchNested.

When a YesodSubDispatchNested instance exists for a nested route type, mkYesodSubDispatch will delegate to it instead of inlining the dispatch. Use mkYesodSubDispatchInstance to generate both YesodSubDispatch and YesodSubDispatchNested instances in one splice.

Methods

WAI subsites

2 declarations
newtypenewtype WaiSubsite
#

Wrap up a normal WAI application as a Yesod subsite. Ignore parent site's middleware and isAuthorized.

Instances8ParseRoute, RenderRoute, YesodSubDispatch, Eq, Ord, Read, …
newtypenewtype WaiSubsiteWithAuth
#

Like WaiSubsite, but applies parent site's middleware and isAuthorized.

Instances8ParseRoute, RenderRoute, YesodSubDispatch, Eq, Ord, Read, …