Reputation: 11
Routing DSL in Akka HTTP does not match regular expressions correctly. I am using version 10.8.1 of Akka HTTP.
I am following the example in the documentation at https://doc.akka.io/docs/akka-http/current/routing-dsl/path-matchers.html, the example:
// matches e.g. /foo/bar123 and extracts "123" as a String
path("foo" / """bar(\d+)""".r)
Here is what I have:
2 paths and 2 routes
roles/members/01cb21e8-7368-4825-856f-c87b44b8c9a0
path("roles" / "members" / s"($uuidRegex)".r) { token =>
roles/permissions/RoleUuid:01cb21e8-7368-4825-856f-c87b44b8c9a0
path("roles" / "permissions" / s"RoleUuid:($uuidRegex)".r) { token =>
in the handler:
val uuidRegex = """[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"""
override val routes: Route = extractRequestContext { implicit rc =>
path("roles" / "members" / s"($uuidRegex)".r) { token =>
get { rc =>
val method = "get role members"
logger.info(s"RoleUUID: method(RoleUUID): $method")
logger.info(s"RoleUUID: token: $token")
val roleUuidOpt = Try {
logger.info(s"RoleUUID: stringToId: converting $token")
RoleUuid(UUID.fromString(token))
}
logger.info(s"RoleUUID: roleUuid: $roleUuidOpt")
rolesOps(rc)
.getMembers(roleUuidOpt.get)
.map(x => completeStr(x.asJson.noSpaces))
}
} ~
path("roles" / "permissions" / s"RoleUuid:($uuidRegex)".r) { token =>
get { rc =>
val method = "get role permissions"
logger.info(s"RoleUUID: method(RoleUUID): $method")
logger.info(s"RoleUUID: token: $token")
val roleUuidOpt = Try {
logger.info(s"RoleUUID: stringToId: converting $token")
RoleUuid(UUID.fromString(token))
}
logger.info(s"RoleUUID: roleUuid: $roleUuidOpt")
rolesOps(rc)
.getRolePermissions(roleUuidOpt.get)
.map(x => completeStr(x.asJson.noSpaces))
}
}
}
The first path (with only the uuid)
roles/members/01cb21e8-7368-4825-856f-c87b44b8c9a0
works, that is it is matched and I see the logging statements
The second path (with the identifier and uuid) roles/permissions/RoleUuid:01cb21e8-7368-4825-856f-c87b44b8c9a0
does not work, it is not matched and I do not see the log statements since I did not see the first log statement, I'm assuming it was never matched
The only difference between the path that works and the one that does not is the prefix in the path matcher.
Upvotes: 1
Views: 2584
Reputation: 19517
Use Scala's String interpolation (notice the s
in front of the last path segment and the $
in front of uuidRegex
):
val uuidRegex = """[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"""
path("roles" / "members" / s"RoleId:($uuidRegex)".r) {
// ...
}
The above path matches, for example, a call to:
http://yourhost:yourport/roles/members/RoleId:d11ffab5-ab40-4e55-9e3e-621df1992470
Upvotes: 1