简体   繁体   English

根据消费者请求构建 Rest API 响应 Object

[英]Building Rest API response Object based on consumers requests

I am building rest API & below are my end points.我正在构建 rest API 及以下是我的终点。

EndPoint 1:

/products/{code} --> giving product inforamtion

Endpoint 2:

/products/{code}/packages --> provides packages for a given productcode

Endpoint 3:

/products/{code}/suppliers --> provides suppliers for a given product code

Endpoint 4:

/products/{code}/shelfTags --> provides shelfTags for a given product code

We have multiple down stream systems(more than 20 downstream systems) which require products & it's related information.我们有多个向下 stream 系统(20 多个下游系统),需要产品及其相关信息。

Note: Not all users require the nested collection information, some clients need only product information and they are good and below are the combinations and it varies by consumers注:并非所有用户都需要嵌套集合信息,有些客户只需要产品信息,它们很好,以下是组合,因消费者而异

1.  product info only --> **consumer 1**
2.  product ,  packages --> **consumer 2**
3.  product, suppliers, packages--> **consumer 3**
4.  product, supplier, packages, shelfTags--> **consumer 4**
5.  product, supplier, shelfTags --> **consumer 5**
6.  product, shelfTags --> **consumer 6**
7.  etc...

From above example, consumer 4 makes Http call to get product code and now has to make multiple Http calls to get packages (Endpoint 2) or suppliers (Endpoint 3) or shelfTags (Endpoint 4) etc... Is this a good design?从上面的例子中,消费者 4调用 Http 来获取产品代码,现在必须调用多个 Http 来获取包裹(端点 2)或供应商(端点 3)或货架标签(端点 4)等......这是一个好的设计吗?

Is there a way consumers can get only what they want in response on one request?有没有一种方法可以让消费者只得到他们想要的东西来响应一个请求? (Now is it a good design to give data needs in one request? or it's good to ask consumers to make multiple Http calls to get nested collection?) (现在在一个请求中提供数据需求是一种好的设计吗?或者要求消费者进行多次 Http 调用以获取嵌套收集是一种好的设计?)

Note: I cannot include all nested collection along with Products Endpoint 1 itself as it's requires huge data querying so I am planning to only provide what consumer may need, that will reduce unnecessary querying and also providing irrelevant information to few consumers who don't need that data.注意:我不能将所有嵌套集合与 Products Endpoint 1 本身一起包括在内,因为它需要大量数据查询,因此我计划只提供消费者可能需要的内容,这将减少不必要的查询,并为少数不需要的消费者提供不相关的信息那个数据。

Current Design:当前设计:

I have below now:我现在有以下:

Approach 1:方法一:

/products/{code}?Options = packages, Suppliers 

Above would give Product details and have options query parameter based on that I can decide whether to pass Packages & supplier, shelftags etc, but here we are not filtering on resource to pass query parameter, I believe this is not a good approach as query params are only used to filter on the resources.上面将给出产品详细信息并有选项查询参数,基于我可以决定是否传递包和供应商、货架标签等,但这里我们没有过滤资源以传递查询参数,我认为这不是查询参数的好方法仅用于过滤资源。

Approach 2:方法二:

Form a different endpoint as query parameter on the resource is for only filters if I am not wrong so looking at below option:形成一个不同的端点,因为资源上的查询参数仅适用于过滤器,如果我没记错的话,请查看以下选项:

/products/{code}/extendedProductDetails?Options = Packages, Suppliers

In option2 extendedProductDetails is an operation rather than resource itself and I am filtering on the operation.在 option2 extendedProductDetails 是一个操作而不是资源本身,我正在过滤操作。

Can anyone provide solution on how to solve this requirement谁能提供有关如何解决此要求的解决方案

Approach 1 vs. Approach 2方法 1方法 2

Assuming that you want to use REST, from my point of view, between the options you gave, I would go with something like Approach 2 , since it is a proper collection for extended information.假设您想使用 REST,从我的角度来看,在您提供的选项之间,我会将 go 与Approach 2类似,因为它是扩展信息的适当集合。 However, I think I'd prefer to model it such as /products-extended/{code}?options=packages,suppliers , since it defines a different collection.但是,我想我更喜欢 model 它,例如/products-extended/{code}?options=packages,suppliers ,因为它定义了不同的集合。

Besides enhancing the readability of the API, in this way, you have the products collection and the products-extended collection: each of them can be consumed independently and with different query string filters (of course that less filtering is prone to increase complexity and latency, but in my opinion, query string parameters should be optional).除了增强 API 的可读性之外,通过这种方式,您还拥有products集合和products-extended集合:它们中的每一个都可以独立使用并使用不同的查询字符串过滤器(当然,较少的过滤容易增加复杂性和延迟,但在我看来,查询字符串参数应该是可选的)。 If they must really not be optional and there is always the need to provide a product id and at least one nested collection, then, you can also consider designing something like products-extended/{code}/{packages,suppliers,etc} .如果它们确实不是可选的,并且总是需要提供product id和至少一个嵌套集合,那么您还可以考虑设计类似products-extended/{code}/{packages,suppliers,etc}的东西。 Either way, this would "protect" your products collection.无论哪种方式,这都会“保护”您的products系列。

Moreover, this would allow you to perform different operations (POST, PUT,...) to both collections, if your use case requires such.此外,如果您的用例需要,这将允许您对 collections 执行不同的操作(POST、PUT、...)。

Other approaches其他方法

Besides the other suggestions on GraphQL - would be great, yes:) -, OData or the custom types, couldn't you keep only with the individual collections?除了关于 GraphQL 的其他建议之外 - 会很棒,是的:) - OData 或自定义类型,你不能只保留单独的 collections 吗? Depending on your use case, maybe you could perform parallel calls to /products/{code}/packages , /products/{code}/suppliers and so on, since you already know the product id .根据您的用例,也许您可以对/products/{code}/packages/products/{code}/suppliers等执行并行调用,因为您已经知道product id Perhaps, the major drawback of this design would be, for example, to create new products.也许,这种设计的主要缺点是,例如,创造新产品。 However, the GET requests became super easy:)但是,GET 请求变得超级简单:)

Maybe a solution would be to use custom media types in the request header:也许解决方案是在请求 header 中使用自定义媒体类型:

application/json+info-only
application/json+supplier
application/json+supplier+packages
etc.

In your controller action you would check for the selected media type and respond to the request based on them.在您的 controller 操作中,您将检查所选媒体类型并根据它们响应请求。 Simply return an IActionResult and your consumer will get the data within one request.只需返回一个 IActionResult,您的消费者就会在一个请求中获取数据。

It's very similar to your approaches but with custom extended media types you would have still one endpoint without additional parameters.它与您的方法非常相似,但使用自定义扩展媒体类型,您仍然可以拥有一个没有附加参数的端点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM