0
# Path Pattern Matching
1
2
Path construction and variable extraction utilities for URL routing, providing type-safe path segment matching and variable extraction from URL paths.
3
4
## Capabilities
5
6
### Path Components
7
8
#### Path and Root
9
10
Core path types for URL pattern matching.
11
12
```scala { .api }
13
/**
14
* Path type alias for Uri.Path
15
*/
16
val Path: Uri.Path.type
17
18
/**
19
* Root path matcher - matches empty path or just "/"
20
*/
21
val Root: Uri.Path.Root.type
22
```
23
24
#### Path Separator (/)
25
26
Path segment separator for building and matching URL paths.
27
28
```scala { .api }
29
/**
30
* Path separator extractor for URL segments
31
* Matches path segments and extracts the last segment as a string
32
*/
33
object / {
34
def unapply(path: Path): Option[(Path, String)]
35
}
36
```
37
38
**Usage Examples:**
39
40
```scala
41
val routes = HttpRoutes.of[IO] {
42
case GET -> Root =>
43
Ok("Root path")
44
45
case GET -> Root / "users" =>
46
Ok("Users list")
47
48
case GET -> Root / "users" / "profile" =>
49
Ok("User profile")
50
51
// Dynamic path segments
52
case GET -> Root / "users" / userId =>
53
Ok(s"User: $userId")
54
}
55
```
56
57
### Path Variable Extractors
58
59
#### Integer Path Variables
60
61
Extract integer values from path segments with automatic parsing and validation.
62
63
```scala { .api }
64
/**
65
* Integer extractor for path variables
66
* Attempts to parse path segment as integer, returns None if parsing fails
67
*/
68
object IntVar extends PathVar[Int] {
69
def unapply(str: String): Option[Int]
70
}
71
```
72
73
**Usage Examples:**
74
75
```scala
76
val routes = HttpRoutes.of[IO] {
77
case GET -> Root / "users" / IntVar(userId) =>
78
Ok(s"User ID: $userId")
79
80
case GET -> Root / "posts" / IntVar(postId) / "comments" / IntVar(commentId) =>
81
Ok(s"Post $postId, Comment $commentId")
82
83
// Non-integer segments won't match
84
case GET -> Root / "users" / "abc" => // This won't match IntVar
85
BadRequest("Invalid user ID")
86
}
87
```
88
89
#### Long Path Variables
90
91
Extract long integer values from path segments.
92
93
```scala { .api }
94
/**
95
* Long integer extractor for path variables
96
* Attempts to parse path segment as long, returns None if parsing fails
97
*/
98
object LongVar extends PathVar[Long] {
99
def unapply(str: String): Option[Long]
100
}
101
```
102
103
**Usage Examples:**
104
105
```scala
106
val routes = HttpRoutes.of[IO] {
107
case GET -> Root / "files" / LongVar(fileId) =>
108
Ok(s"File ID: $fileId")
109
110
case POST -> Root / "transactions" / LongVar(transactionId) =>
111
Ok(s"Transaction: $transactionId")
112
}
113
```
114
115
#### UUID Path Variables
116
117
Extract UUID values from path segments with automatic parsing and validation.
118
119
```scala { .api }
120
/**
121
* UUID extractor for path variables
122
* Attempts to parse path segment as UUID, returns None if parsing fails
123
*/
124
object UUIDVar extends PathVar[java.util.UUID] {
125
def unapply(str: String): Option[java.util.UUID]
126
}
127
```
128
129
**Usage Examples:**
130
131
```scala
132
import java.util.UUID
133
134
val routes = HttpRoutes.of[IO] {
135
case GET -> Root / "users" / UUIDVar(userId) =>
136
Ok(s"User UUID: $userId")
137
138
case DELETE -> Root / "sessions" / UUIDVar(sessionId) =>
139
Ok(s"Session $sessionId deleted")
140
141
// Invalid UUIDs won't match
142
case GET -> Root / "users" / "not-a-uuid" => // Won't match UUIDVar
143
BadRequest("Invalid UUID format")
144
}
145
```
146
147
### Advanced Path Matching
148
149
#### Path Head/Tail Extractor (/:)
150
151
Extract the first path segment and remaining path.
152
153
```scala { .api }
154
/**
155
* Path head/tail extractor
156
* Extracts first segment as string and remaining path
157
*/
158
object /: {
159
def unapply(path: Path): Option[(String, Path)]
160
}
161
```
162
163
**Usage Examples:**
164
165
```scala
166
val routes = HttpRoutes.of[IO] {
167
case GET -> ("api" /: "v1" /: rest) =>
168
Ok(s"API v1 endpoint, remaining path: $rest")
169
170
case GET -> (first /: second /: _) =>
171
Ok(s"First: $first, Second: $second")
172
}
173
```
174
175
#### File Extension Matching (~)
176
177
Extract file extensions from path segments or filenames.
178
179
```scala { .api }
180
/**
181
* File extension extractor for paths and strings
182
* For paths: extracts base path and extension
183
* For strings: extracts base name and extension
184
*/
185
object ~ {
186
def unapply(path: Path): Option[(Path, String)]
187
def unapply(fileName: String): Option[(String, String)]
188
}
189
```
190
191
**Usage Examples:**
192
193
```scala
194
val routes = HttpRoutes.of[IO] {
195
// Match files with extensions
196
case GET -> Root / "files" / (fileName ~ ext) =>
197
Ok(s"File: $fileName, Extension: $ext")
198
199
// Match specific extensions
200
case GET -> Root / "images" / (name ~ "jpg") =>
201
Ok(s"JPEG image: $name")
202
203
case GET -> Root / "docs" / (name ~ "pdf") =>
204
Ok(s"PDF document: $name")
205
206
// Path-based extension matching
207
case GET -> path ~ "json" =>
208
Ok("JSON endpoint")
209
}
210
```
211
212
### Matrix Variables
213
214
Advanced path parameter extraction using matrix URI syntax.
215
216
```scala { .api }
217
/**
218
* Abstract base class for matrix variable extraction
219
* Matrix variables use semicolon syntax: /path;param1=value1;param2=value2
220
*/
221
abstract class MatrixVar[F[_]: Foldable](name: String, domain: F[String]) {
222
def unapplySeq(str: String): Option[Seq[String]]
223
}
224
```
225
226
**Usage Examples:**
227
228
```scala
229
// Define custom matrix variable extractor
230
object BoardVar extends MatrixVar("square", List("x", "y"))
231
232
val routes = HttpRoutes.of[IO] {
233
// Matches: /board/square;x=5;y=3
234
case GET -> Root / "board" / BoardVar(IntVar(x), IntVar(y)) =>
235
Ok(s"Board position: ($x, $y)")
236
237
// Matches: /config/settings;debug=true;level=info
238
object ConfigVar extends MatrixVar("settings", List("debug", "level"))
239
case GET -> Root / "config" / ConfigVar(debug, level) =>
240
Ok(s"Debug: $debug, Level: $level")
241
}
242
```
243
244
### Path Pattern Integration
245
246
Path patterns integrate with other DSL components:
247
248
```scala
249
val routes = HttpRoutes.of[IO] {
250
// Combine with query parameters
251
case GET -> Root / "search" / query :? Limit(limit) =>
252
Ok(s"Search: $query, Limit: $limit")
253
254
// Combine with request processing
255
case req @ POST -> Root / "users" / IntVar(userId) =>
256
req.as[UserUpdate].flatMap { update =>
257
Ok(s"Updated user $userId")
258
}
259
260
// Complex path matching
261
case GET -> Root / "api" / "v1" / "users" / IntVar(id) / "posts" / IntVar(postId) =>
262
Ok(s"User $id, Post $postId")
263
}
264
```