Path construction and variable extraction utilities for URL routing, providing type-safe path segment matching and variable extraction from URL paths.
Core path types for URL pattern matching.
/**
* Path type alias for Uri.Path
*/
val Path: Uri.Path.type
/**
* Root path matcher - matches empty path or just "/"
*/
val Root: Uri.Path.Root.typePath segment separator for building and matching URL paths.
/**
* Path separator extractor for URL segments
* Matches path segments and extracts the last segment as a string
*/
object / {
def unapply(path: Path): Option[(Path, String)]
}Usage Examples:
val routes = HttpRoutes.of[IO] {
case GET -> Root =>
Ok("Root path")
case GET -> Root / "users" =>
Ok("Users list")
case GET -> Root / "users" / "profile" =>
Ok("User profile")
// Dynamic path segments
case GET -> Root / "users" / userId =>
Ok(s"User: $userId")
}Extract integer values from path segments with automatic parsing and validation.
/**
* Integer extractor for path variables
* Attempts to parse path segment as integer, returns None if parsing fails
*/
object IntVar extends PathVar[Int] {
def unapply(str: String): Option[Int]
}Usage Examples:
val routes = HttpRoutes.of[IO] {
case GET -> Root / "users" / IntVar(userId) =>
Ok(s"User ID: $userId")
case GET -> Root / "posts" / IntVar(postId) / "comments" / IntVar(commentId) =>
Ok(s"Post $postId, Comment $commentId")
// Non-integer segments won't match
case GET -> Root / "users" / "abc" => // This won't match IntVar
BadRequest("Invalid user ID")
}Extract long integer values from path segments.
/**
* Long integer extractor for path variables
* Attempts to parse path segment as long, returns None if parsing fails
*/
object LongVar extends PathVar[Long] {
def unapply(str: String): Option[Long]
}Usage Examples:
val routes = HttpRoutes.of[IO] {
case GET -> Root / "files" / LongVar(fileId) =>
Ok(s"File ID: $fileId")
case POST -> Root / "transactions" / LongVar(transactionId) =>
Ok(s"Transaction: $transactionId")
}Extract UUID values from path segments with automatic parsing and validation.
/**
* UUID extractor for path variables
* Attempts to parse path segment as UUID, returns None if parsing fails
*/
object UUIDVar extends PathVar[java.util.UUID] {
def unapply(str: String): Option[java.util.UUID]
}Usage Examples:
import java.util.UUID
val routes = HttpRoutes.of[IO] {
case GET -> Root / "users" / UUIDVar(userId) =>
Ok(s"User UUID: $userId")
case DELETE -> Root / "sessions" / UUIDVar(sessionId) =>
Ok(s"Session $sessionId deleted")
// Invalid UUIDs won't match
case GET -> Root / "users" / "not-a-uuid" => // Won't match UUIDVar
BadRequest("Invalid UUID format")
}Extract the first path segment and remaining path.
/**
* Path head/tail extractor
* Extracts first segment as string and remaining path
*/
object /: {
def unapply(path: Path): Option[(String, Path)]
}Usage Examples:
val routes = HttpRoutes.of[IO] {
case GET -> ("api" /: "v1" /: rest) =>
Ok(s"API v1 endpoint, remaining path: $rest")
case GET -> (first /: second /: _) =>
Ok(s"First: $first, Second: $second")
}Extract file extensions from path segments or filenames.
/**
* File extension extractor for paths and strings
* For paths: extracts base path and extension
* For strings: extracts base name and extension
*/
object ~ {
def unapply(path: Path): Option[(Path, String)]
def unapply(fileName: String): Option[(String, String)]
}Usage Examples:
val routes = HttpRoutes.of[IO] {
// Match files with extensions
case GET -> Root / "files" / (fileName ~ ext) =>
Ok(s"File: $fileName, Extension: $ext")
// Match specific extensions
case GET -> Root / "images" / (name ~ "jpg") =>
Ok(s"JPEG image: $name")
case GET -> Root / "docs" / (name ~ "pdf") =>
Ok(s"PDF document: $name")
// Path-based extension matching
case GET -> path ~ "json" =>
Ok("JSON endpoint")
}Advanced path parameter extraction using matrix URI syntax.
/**
* Abstract base class for matrix variable extraction
* Matrix variables use semicolon syntax: /path;param1=value1;param2=value2
*/
abstract class MatrixVar[F[_]: Foldable](name: String, domain: F[String]) {
def unapplySeq(str: String): Option[Seq[String]]
}Usage Examples:
// Define custom matrix variable extractor
object BoardVar extends MatrixVar("square", List("x", "y"))
val routes = HttpRoutes.of[IO] {
// Matches: /board/square;x=5;y=3
case GET -> Root / "board" / BoardVar(IntVar(x), IntVar(y)) =>
Ok(s"Board position: ($x, $y)")
// Matches: /config/settings;debug=true;level=info
object ConfigVar extends MatrixVar("settings", List("debug", "level"))
case GET -> Root / "config" / ConfigVar(debug, level) =>
Ok(s"Debug: $debug, Level: $level")
}Path patterns integrate with other DSL components:
val routes = HttpRoutes.of[IO] {
// Combine with query parameters
case GET -> Root / "search" / query :? Limit(limit) =>
Ok(s"Search: $query, Limit: $limit")
// Combine with request processing
case req @ POST -> Root / "users" / IntVar(userId) =>
req.as[UserUpdate].flatMap { update =>
Ok(s"Updated user $userId")
}
// Complex path matching
case GET -> Root / "api" / "v1" / "users" / IntVar(id) / "posts" / IntVar(postId) =>
Ok(s"User $id, Post $postId")
}