【问题标题】:JAX-RS: Implement multiple operations through query parametersJAX-RS:通过查询参数实现多种操作
【发布时间】:2014-03-18 07:17:11
【问题描述】:

我有一项服务支持多种操作 A、B 和 C。

每个操作都有不同的参数。我的架构师希望我使用以下 URL 为每个操作实现这些操作:

http://<server>:<port>/application/service?q=A&<query_paramers>
http://<server>:<port>/application/service?q=B&<query_paramers>
http://<server>:<port>/application/service?q=C&<query_paramers>

即他希望我接受操作名称作为查询参数,而不是作为路径参数。

现在的问题是每个操作都有相同的基本 URL,即

http://<server>:<port>/application/service

根据我的理解,如果我需要支持这种格式,那么在我的服务中,它将作为资源公开的单个方法,在该方法中基于“q”的值,我将决定调用哪个操作.

虽然它看起来会起作用,但我对这种方法没有什么顾虑

  1. 将公开代表所有三个操作的单个资源,这对我来说看起来不正确。我不确定这方面的行业标准,但我认为资源和应用程序操作/行为之间应该存在一对一的映射关系。

  2. 单个资源将接受所有操作的参数,这意味着语法将包含单个资源下列出的所有参数,用户将无法找出哪个参数属于哪个操作。

  3. 在单个方法中接受 3 个操作的所有参数的一种解决方法是,我的方法采用单个 @Context UriContext 参数,但在这种情况下,我的语法将不列出任何参数,这又是错误的用户将不会获得有关每个操作的可能参数的任何信息。

提前致谢。

【问题讨论】:

    标签: java web-services rest jakarta-ee jax-rs


    【解决方案1】:

    您的想法是正确的:如果所谓的“架构师”告诉您只使用 GET 请求(或单个 HTTP 方法)进行此操作,那么您唯一的方法就是拥有一个单一的资源方法,其中基于参数q 的值你调用了一些不同的方法。 与您的担忧相关:

    1. 您将只有一个资源方法来处理这三个请求,这很糟糕。但是,如果您有一个单一的 RESOURCE(即类)来处理具有三种资源方法的所有这些请求,那也不错。
    2. 没错。此解决方案的优点是参数的解组是自动为您进行的(例如,您将直接获得 Long 参数或 Enum,而无需手动解码它们)。
    3. 您可以从UriInfo 实例中获取所有GET 参数,如果您使用@Context UriInfo uriInfo 之类的参数注入一个参数(请参阅getQueryParameters())。缺点是您将手动解组它们并相应地传递给一些具有明确签名的私有方法。

    PS:询问您的架构师他这样做的原因。如果您更改数据库中的数据,发出 GET 请求可能是个坏主意(想象一下,只需复制 URL 并将其粘贴到浏览器中)。除此之外,这是糟糕的代码,您将在其中进行更多调试(想象一下,您稍后会得到除q=a, q=b, q=c 之外的其他 10 个案例)。

    【讨论】:

    • 感谢您的信息。即使我使用 UriInfo,我的语法也不会很好看。由于用户不会获得与特定操作和语法相关的参数的任何信息,因此他将看到该资源的单个 uriInfo,这看起来不太好。
    • 是的,资源方法的语法/签名看起来不太好,但是该方法可以使用正确的类型/参数(带有一个很好的签名)调用其他 3 个方法(getQueryParameters() 返回一个MultivaluedMap)。但这就是我所说的“坏代码”。
    • 感谢您清理空气。我将与他讨论这种方法的利弊,看看他的想法。
    • 不客气。只是不要忘记稍后接受答案。
    【解决方案2】:

    这三个操作是什么? CRUD 操作?

    REST 方面的查询参数被视为具有规范的 GET 资源(具体的 where 子句)

    不建议将所有类型的操作都赋予与查询参数相同的方法。

    使用@Path 更改路径。如果你希望所有的服务都托管在同一个路径下,那么使用Http方法来区分操作。

    如果操作是创建资源...

    然后使用@POST 将资源信息作为参数。

    如果你愿意

    Create the resource - @POST
    retrieve the data   - @GET
    update the data     - @PUT
    delete the data     - @DELETE
    

    资源:

    1. link 为您提供有关 HTTP 方法的详细信息。
    2. link 给出了如何使用 @Path 和 http 方法的示例

    【讨论】:

    • 所有操作都是GET操作。我知道如果需要将它们实现为单独的资源(使用@Path),我应该如何处理,但这里的问题是如何实现相同的,如果我需要使用查询参数来实现它。 AFAIK,@Path 不支持提及查询参数。如果您知道任何替代方案,请分享。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    相关资源
    最近更新 更多