我使用 Ratpack 和 Groovy 创建了一个 API。我想要一个 POST API,以便数据应该被处理并存储在 2 个 cassandra 数据库中,比如表 A 和表 B。现在,我的 Ratpack.groovy 中有这个,因此每当必须推送数据时,我都必须调用这两个 API:
prefix("A") {
post { registry.get(PostEndpointA).handle(context) }
}
prefix("B") {
post { registry.get(PostEndpointB).handle(context) }
}
我想要像这样的单个 POST API 调用,以便通过单个 API 调用可以将请求一起委托给两个端点:
prefix("post") {
post { registry.get(PostEndpointA).handle(context) }
post { registry.get(PostEndpointB).handle(context) }
}
或者,我想要这个:
prefix("post") {
post { registry.get(PostEndpoint).handle(context) }
}
在后端点中,我可以按如下方式执行这两个操作:
saveJsonAsA(context)
.promiseSingle()
.then { ItemA updatedItem ->
context.response.headers
.add(HttpHeaderNames.LOCATION, "/item/api/A")
context.response.status(HttpResponseStatus.CREATED.code())
.send()
}
saveJsonAsB(context)
.promiseSingle()
.then { ItemB updatedItem ->
context.response.headers
.add(HttpHeaderNames.LOCATION, "/item/api/B")
context.response.status(HttpResponseStatus.CREATED.code())
.send()
}
在这两种情况下,该项仅添加到表 A,而不是 B 或前面代码中写入的任何内容。
注意 ItemA 和 ItemB 的 DB 基本相同,只是主键不同,方便 GET 从 2 种方式进行。知道如何在 Ratpack 中做到这一点吗?
如果我理解正确,您可以尝试做类似的事情:
@Grab('io.ratpack:ratpack-groovy:1.3.3')
import static ratpack.groovy.Groovy.ratpack
import ratpack.http.Status
import ratpack.exec.Promise
import com.google.common.reflect.TypeToken
class ServiceA {
Promise<String> save(json) {
Promise.value(json)
}
}
class ServiceB {
Promise<String> save(json) {
Promise.value(json)
}
}
ratpack {
bindings {
bindInstance new ServiceA()
bindInstance new ServiceB()
}
handlers {
post(':name') { // parameterize on path token
def name = pathTokens.get('name') // extract token
def service = null
switch(name) {
case 'A':
service = get(ServiceA) // extract appropriate service
break
case 'B':
service = get(ServiceB) // extract appropriate service
break
}
parse(new TypeToken<Map<String, Object>>(){})
.flatMap(service.&save) // save your extracted item
.then {
response.headers.add('Location', "/item/api/$name")
response.status(Status.of(201))
response.send()
}
}
}
}
示例卷发看起来像这样
$ curl -X POST -H'Content-Type: application/json' -d '{"foo":"bar"}' -v localh ost:5050/A
< HTTP/1.1 201 Created
< Location: /item/api/A
< content-length: 0
< connection: keep-alive
$ curl -X POST -H'Content-Type: application/json' -d '{"foo":"bar"}' -v localh ost:5050/B
< HTTP/1.1 201 Created
< Location: /item/api/B
< content-length: 0
< connection: keep-alive
从您发布的问题数量来看,我建议您注册 Ratpack 社区松弛频道 https://slack-signup.ratpack.io/
我们使用rxJava来做到这一点:
Single
.zip(
service.add(cv1),
service.add(cv2),
(a, b) -> new Object[] { a, b }
)
.blockingGet();
我们将其包装在一个承诺中,并在then
块中处理数组。