在 Play 中按参数数据类型路由

Routing by param data type in Play

在 Play 中,根据提供的数据类型处理端点路由的最佳方法是什么?

GET /my/:id            controllers.MyController.getById(id: Long)
GET /my/:name          controllers.MyController.getByName(name: String)

getById 应该被称为 GET /my/1
getByName 应该为 GET /my/bob 调用(因为 bob 不会转换为 Long

这可能并不总是最好的端点设计,但如果需要,实现这一点的最佳方法是什么?

this answer 中提到的一种解决方法是创建单个控制器方法来为您尝试转换。

GET /my/:arg            controllers.MyController.getByAny(arg: String)

Result getByAny(String arg) {
    try {
        getById( Long.parseLong(arg)) ;
    } catch (Exception e) {
        return getByName(arg)
    }
}

这样做的一个缺点是,如果使用 Swagger 文档,您不再为每个路由提供单独的文档。
您还必须为每个冲突的路由组单独执行此操作。

有没有一种方法可以在不破坏文档的情况下向所有端点而不是一个接一个地添加类似功能?

尝试使用 custom patterns

GET   /items/$id<[0-9]+>    controllers.Items.getById(id: Long)
GET   /items/$name<[a-zA-Z]+>    controllers.Items.getByName(name)

事实上,第二个可能被简化为:

GET   /items/:name    controllers.Items.getByName(name)

当多条路由匹配时,应选择第一个匹配的路由。