使用 Ratpack 和 Groovy 发布 API 给出 405 错误和 RxJava 方法不起作用



我正在使用RatpackGroovy构建API。POST API 始终提供:

405 方法未找到错误

这是来自 POST 终结点处理程序的代码段。在此代码中,promiseSinglethenobservemapdoOnNextdoOnError等。

RxJAVA函数不起作用。有什么原因导致RxJava方法不起作用吗?

saveJsonAsData(context, id)
            .promiseSingle()
            .then { Data updateddata ->
                context.response.headers
                    .add(HttpHeaderNames.LOCATION, "/api/save/${updateddata.id}/${updateddata.value}")
                context.response.status(HttpResponseStatus.CREATED.code())
                    .send()
            }
    }
    protected Observable<Data> saveJsonAsData(GroovyContext context, String id) {
        context.request.body.observe()
            .map { TypedData typedData -> extractData(context, typedData) }
            .doOnNext { Data data ->
                data.id = id
                validatorWrapper.validate(data)
            }
            .flatMap(data.&save as Func1)
            .doOnError { Throwable throwable -> log.error("Error saving data", throwable) }
    }

问题不在于 Rx,而在于上下文的使用。

您应该尝试将响应处理逻辑保留在处理程序中,即不要传递上下文,而是获取所需的对象并将它们传递给您的服务。

举个例子

path('myendpoint') { MyRxService service ->
  byMethod {
    get {
      // do something when request is GET
    }
    post {
      request.body.map { typedData ->
        extractItem(typeData) // extract your item from the request first
      }.flatMap { item ->
          service.saveJsonAsItemLocation(item).promiseSingle() // then once it's extracted pass the item to your "saveJsonAsItemLocation" method
      }.then { ItemLocationStore updatedItem ->
          response.headers.add(HttpHeaderNames.LOCATION, "/itemloc/v1/save/${updatedItem.tcin}/${updatedItem.store}")
          context.response.status(HttpResponseStatus.CREATED.code()).send()
      }
    }
  }
}

我的猜测是你有这样的东西:

get {
 // get stuff
}
post {
  // post stuff
}

这不起作用的原因是 Ratpack 不使用路由表来处理传入的请求,而是使用链委托。get {}绑定到根路径和 GET http 方法,post {}绑定到根路径和 POST http 方法。由于get {}与路径匹配,因此 Ratpack 认为处理程序匹配,并且由于处理程序适用于GET因此它将其视为 405。

有一些链方法可以绑定,而不管HTTP方法如何,例如all {}path {}。Chain#all 将处理所有路径和方法,其中 Chain#path(String) 与特定路径匹配。

希望这有帮助。