自Lagom 1.5.0以来,可以使用额外的Play路由器来扩展Lagom服务。
这在将Lagom与现有的Play路由器集成时尤其有用,例如Play gRPC Router ,或者您可以使用的任何其他Play路由器。在连接Lagom服务器时,需要添加一个额外的路由器。在连接Lagom服务器之后,您将附加额外的Play路由器。
override lazy val lagomServer =
serverFor[HelloService](wire[HelloServiceImpl])
.additionalRouter(wire[SomePlayRouter])
文件上传示例
下面的示例显示了如何将文件上载端点添加到现有的Lagom服务。
该示例基于 ScalaSirdRouter ,允许以编程方式构建Play路由器。它添加了一个额外的路径(/api/files
),用于接收对多部分表单数据的POST调用。
import play.api.mvc.DefaultActionBuilder
import play.api.mvc.PlayBodyParsers
import play.api.mvc.Results
import play.api.routing.Router
import play.api.routing.sird._
class FileUploadRouter(action: DefaultActionBuilder, parser: PlayBodyParsers) {
val router = Router.from {
case POST(p"/api/files") =>
action(parser.multipartFormData) { request =>
val filePaths = request.body.files.map(_.ref.getAbsolutePath)
Results.Ok(filePaths.mkString("Uploaded[", ", ", "]"))
}
}
}
在应用程序加载器中,可以连接路由器并将其附加到Lagom服务中。
override lazy val lagomServer =
serverFor[HelloService](wire[HelloServiceImpl])
.additionalRouter(wire[FileUploadRouter].router)
路径/api/files
将在Lagom服务中提供:
curl -X POST -F "data=@somefile.txt" -v http://localhost:65499/api/files
请注意,在该示例中,我们没有使用服务网关来访问应用程序。我们使用服务端口直接调用它,在本例中为65499。
服务网关注意事项
附加路由器不是应用程序ServiceDescriptor
的一部分,因此无法在开发模式下自动作为端点发布到服务网关。如果希望通过网关访问其他路由器,则需要在ServiceDescriptor
定义中显式地为其添加ACL(Access Control List,访问控制列表)。
trait HelloService extends Service {
def hello(id: String): ServiceCall[NotUsed, String]
final override def descriptor = {
import Service._
named("hello")
.withCalls(
pathCall("/api/hello/:id", hello _).withAutoAcl(true)
)
.withAcls(
// extra ACL to expose additional router endpoint on ServiceGateway
ServiceAcl(pathRegex = Some("/api/files"))
)
}
}
在服务网关上发布路径后,您可以调用:
curl -X POST -F "data=@somefile.txt" -v http://localhost:9000/api/files
注意9000端口的使用(Lagom的开发模式ServiceGateway)
Lagom客户端注意事项
其他路由器不是服务API的一部分,因此无法从生成的Lagom客户端访问。Lagom客户端只能访问服务特质接口上定义的方法。额外的路由器只是公开的HTTP端点的一部分。要访问,您需要使用HTTP客户端,例如:Play-WS 。