Derive type-safe fetch clients from purescript-yoga-http-api route definitions.
spago install yoga-fetch-omimport Yoga.Fetch.Om.Simple (get, post)
type User = { id :: Int, name :: String, email :: String }
main = do
-- Simple GET request
user <- get @User "https://api.example.com/users/42" {}
log user.name
-- Simple POST request with JSON body
newUser <- post @User "https://api.example.com/users" {} { name: "Alice", email: "alice@example.com" }
log $ "Created user with ID: " <> show newUser.idtype UserAPI =
{ getUser ::
Route GET ("users" / "id" : Int) {}
( ok :: { body :: User }
, notFound :: { body :: ErrorMessage }
)
, listUsers ::
Route GET ("users" :? { limit :: Int, offset :: Int }) {}
( ok :: { body :: Array User } )
, createUser ::
Route POST "users" { body :: JSON CreateUserRequest }
( created :: { body :: User }
, badRequest :: { body :: ErrorMessage }
)
, updateUser ::
Route PUT ("users" / "id" : Int) { body :: JSON UpdateUserRequest }
( ok :: { body :: User }
, notFound :: { body :: ErrorMessage }
, badRequest :: { body :: ErrorMessage }
)
, deleteUser ::
Route DELETE ("users" / "id" : Int) {}
( noContent :: { body :: {} }
, notFound :: { body :: ErrorMessage }
)
}
api = client @UserAPI "https://api.example.com"
-- Create a user
user <- api.createUser { name: "Alice", email: "alice@example.com" }
# handleErrors
{ badRequest: \err -> do
log $ "Validation error: " <> err.error
throw err
}
-- Update with path param + body
updated <- api.updateUser { id: user.id } { name: "Alice Updated", email: user.email }
# handleErrors
{ notFound: \_ -> throw userNotFound
, badRequest: \err -> throw validationError
}
-- Query with pagination
users <- api.listUsers { limit: 10, offset: 0 }See the test files for complete, runnable examples with all imports:
test/Simple.Spec.purs- Basic GET/POST/PUT/PATCH/DELETE requeststest/Complete.Example.purs- Full CRUD API with error handlingtest/BuildUrl.Spec.purs- Path parameters and query stringstest/Variant.Spec.purs- Response variant handlingtest/SplitParams.Spec.purs- Parameter extraction patterns
- Path parameters:
/users/:idrequires{ id: Int } - Query parameters: Type-safe query strings with
? - Request bodies: Automatic JSON serialization
- Response bodies: Automatic JSON parsing
- Error handling: Exhaustive pattern matching on variants
Define your API once, use it everywhere:
-- Server (yoga-fastify-om)
server = buildServer apiRoutes handlers
-- Client (yoga-fetch-om)
apiClient = client @apiRoutes baseUrlChanges to routes automatically update both client and server!
No manual client code:
- ✅ URL building with path parameter substitution
- ✅ Query string construction
- ✅ JSON request serialization
- ✅ JSON response parsing
- ✅ Status code → variant mapping
- ✅ CORS and credentials handling
Works seamlessly with the Om monad:
getUserProfile :: Om AppContext AppErrors User
getUserProfile = do
{ api, userId } <- ask
api.getUser { id: userId }
# handleErrors { notFound: \_ -> throw { userNotFound: userId } }The library uses PureScript's type system to:
-
Extract parameters from route definitions at compile time
- Path params:
"users" / "id" : Int→{ id :: Int } - Query params:
:? { limit :: Int }→{ limit :: Int } - Body params:
{ body :: JSON User }→ request body
- Path params:
-
Build URLs automatically
- Pattern:
/users/:id+ params:{ id: 42 }→/users/42 - Query:
?limit=10&offset=20
- Pattern:
-
Make requests with
js-fetchandjs-promise-aff -
Parse responses by mapping status codes to variant labels
200→"ok",404→"notFound", etc.
All automatically based on your route types!
client :: forall @routes. String -> Record clientsDerives a record of client functions from a record of routes using Visible Type Application.
Parameters:
@routes- Your API route type (provided via VTA syntax)baseUrl- Base URL (e.g.,"https://api.example.com")
Returns: Record where each route becomes a function returning Om context errors result
Example:
api = client @UserAPI "https://api.example.com"- ✅ Core client derivation with VTA syntax
- ✅ All HTTP methods (GET, POST, PUT, PATCH, DELETE)
- ✅ Path, query, and body parameters
- ✅ Request/response headers
- ✅ JSON encoding/decoding
- ✅ FormData support
- ✅ Variant response handling
- ✅ Om monad integration
MIT
- purescript-yoga-http-api - HTTP API type definitions
- purescript-yoga-fastify-om - Server-side counterpart
- purescript-yoga-json - JSON serialization
- purescript-yoga-om - Om monad