liveBook · Manning

(:>)

As explained in Learn Haskell by Example

(:>) is a Servant type operator that combines route or request information into the description of one API operation.

(:>) is Servant’s type-level operator for building one API operation from smaller pieces. Read it left to right: route segments and request requirements appear before the final HTTP method and response description. A type such as "simple" :> "example" :> GetNoContent describes a GET endpoint at /simple/example with no response content. section 17.1.1

Use (:>) to add the information an operation needs. Literal path pieces define the route; Get '[JSON] SomeType specifies a JSON response; ReqBody '[JSON] SomeType requires a JSON request body; and Capture "id" Int supplies a typed path parameter. Servant can automatically reject a request body that does not match its declared specification. section 17.1.1

A small todo API

Each branch describes one operation, while (:>) keeps that operation’s route, inputs, and result together: type TodoApi = "entries" :> Get '[JSON] [TodoEntry] :<|> "add" :> ReqBody '[JSON] TodoEntry :> PostCreated '[JSON] Int :<|> "toggle" :> Capture "id" Int :> PatchNoContent Here, entries returns todo entries, add accepts a TodoEntry and returns a created identifier, and toggle takes an integer id. (:>) builds each branch; (:<|>) joins branches into the complete API. section 17.1.1

Listing 17.1 A type for the todo list API server
{-# LANGUAGE TypeOperators #-}     #1
{-# LANGUAGE DataKinds #-}        #1
module Todos.Api where

import Servant.API
import Todos.Types

type TodoApi =
  "entries" :> Get '[JSON] [TodoEntry]        #2
    :<|> "add" :> ReqBody '[JSON] TodoEntry :>
 PostCreated '[JSON] Int                       #3
    :<|> "toggle" :> Capture "id" Int :> PatchNoContent    #4

Inspect the complete API type to see how route literals, request bodies, captures, HTTP methods, and response types chain through (:>). section 17.1.1

API declarations need the DataKinds and TypeOperators language extensions. Their mechanics are deliberately left aside: the practical task is to write the API type and then provide handlers that match it. Servant statically checks an implementation against the declared API, including endpoint coverage, parameters, and returned data types. section 17.1.1 section 17.1.3

How Learn Haskell by Example covers it

How deep it goes
Explains chained endpoint declarations through routes, JSON responses, request bodies, and captures, while deferring DataKinds and TypeOperators internals.
Examples
Uses simple GET routes plus todo-list entries, add, and toggle operations.
What it assumes
Teaches practical declaration usage while assuming no explanation of DataKinds or TypeOperators internals.
What you can do after
Apply it via Servant to declare typed API operations that handlers must match.
How it connects
Connects Servant API types with (:<|>), Get, ReqBody, Capture, JSON, and HTTP methods.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.