如何在播放框架中访问 Web 服务 API 时传递可选参数?
How to pass optional parameters while accessing web service API in play framework?
我是框架新手,正在尝试集成微服务。我正在使用 WSClient 调用 Web 服务。为了调用 POST rest API,我传递了包含一些必需参数和一些可选参数的请求正文。我的问题是如何在这里传递可选参数?
我的代码示例是
def add = Action.async { implicit request =>
UserDataForm.bindFromRequest.fold(
profileForm => {
val response = profileForm.errorsAsJson
Future(BadRequest(response).as("application/json"))
},
userData => try {
ws.url("http://localhost:9000/" + "api/profile")
.post(
Map("userId" -> userData.userId, "firstName" -> userData.firstName, "lastName" -> userData.lastName, "country" -> userData.country, "address" -> userData.address)).map { response =>
OutputWithErrors(response.body, response.status)
}
} catch {
case e: Exception =>
Future(BadRequest(Message(false, e.getMessage).toJson.prettyPrint).as("application/json"))
})
}
所以这里的address
是可选参数
并形成数据,即 userData
这里
case class UserForm(userId: String, firstName: String, lastName: String, country: String, address: Option[String])
val UserDataForm = Form(
mapping(
"userId" -> nonEmptyText,
"firstName" -> nonEmptyText,
"lastName" -> nonEmptyText,
"country" -> nonEmptyText,
"address" -> optional(text)
)(UserForm.apply)(UserForm.unapply)
)
因此在 ws.url(...)post(Map("userId" -> userData, ...))
附近调用休息服务 API 时,编译器抱怨 No implicits found for parameter evidence: BodyWritable[Map[String, Serializable]]
这里的问题是您要传递给 post
的 Map
。除了一个条目之外的所有条目都是 (String, String)
,但最后一个条目是 (String, Option[String])
.
编译器现在必须弄清楚这个集合的类型可能是什么,并沿着类型层次上升。它能计算出的最佳类型是 Map[String, Serializable]
。因为那是最窄的超类型 String 和 Option 实现。
这是 post 的定义:
def post[T: BodyWritable](body: T): Future[Response]
你可以看到 T 上有一个类型约束,这意味着你需要一个隐式转换器*用于传递给 post 到 BodyWritable
的主体。您可以在 DefaultBodyWritables 中找到隐式 BodyWritables。而且没有BodyWritable[Map[String, Serializable]]
。但是有一个 Map[String, String]
你必须选择:
- 更改地图,使其具有
Map[String, String]
类型,方法是通过 getOrElse
为 address
提供默认值,或者不向地图添加地址,如果它是 None.
- 为 Map[String, Serializable] 写一个 BodyWritable。 (这可能无法以令人满意的方式实现)
我建议你选择#1。
* 如果这不是此类隐式的正确术语,请纠正我。
我是框架新手,正在尝试集成微服务。我正在使用 WSClient 调用 Web 服务。为了调用 POST rest API,我传递了包含一些必需参数和一些可选参数的请求正文。我的问题是如何在这里传递可选参数?
我的代码示例是
def add = Action.async { implicit request =>
UserDataForm.bindFromRequest.fold(
profileForm => {
val response = profileForm.errorsAsJson
Future(BadRequest(response).as("application/json"))
},
userData => try {
ws.url("http://localhost:9000/" + "api/profile")
.post(
Map("userId" -> userData.userId, "firstName" -> userData.firstName, "lastName" -> userData.lastName, "country" -> userData.country, "address" -> userData.address)).map { response =>
OutputWithErrors(response.body, response.status)
}
} catch {
case e: Exception =>
Future(BadRequest(Message(false, e.getMessage).toJson.prettyPrint).as("application/json"))
})
}
所以这里的address
是可选参数
并形成数据,即 userData
这里
case class UserForm(userId: String, firstName: String, lastName: String, country: String, address: Option[String])
val UserDataForm = Form(
mapping(
"userId" -> nonEmptyText,
"firstName" -> nonEmptyText,
"lastName" -> nonEmptyText,
"country" -> nonEmptyText,
"address" -> optional(text)
)(UserForm.apply)(UserForm.unapply)
)
因此在 ws.url(...)post(Map("userId" -> userData, ...))
附近调用休息服务 API 时,编译器抱怨 No implicits found for parameter evidence: BodyWritable[Map[String, Serializable]]
这里的问题是您要传递给 post
的 Map
。除了一个条目之外的所有条目都是 (String, String)
,但最后一个条目是 (String, Option[String])
.
编译器现在必须弄清楚这个集合的类型可能是什么,并沿着类型层次上升。它能计算出的最佳类型是 Map[String, Serializable]
。因为那是最窄的超类型 String 和 Option 实现。
这是 post 的定义:
def post[T: BodyWritable](body: T): Future[Response]
你可以看到 T 上有一个类型约束,这意味着你需要一个隐式转换器*用于传递给 post 到 BodyWritable
的主体。您可以在 DefaultBodyWritables 中找到隐式 BodyWritables。而且没有BodyWritable[Map[String, Serializable]]
。但是有一个 Map[String, String]
你必须选择:
- 更改地图,使其具有
Map[String, String]
类型,方法是通过getOrElse
为address
提供默认值,或者不向地图添加地址,如果它是 None. - 为 Map[String, Serializable] 写一个 BodyWritable。 (这可能无法以令人满意的方式实现)
我建议你选择#1。
* 如果这不是此类隐式的正确术语,请纠正我。