API建模:同名的两个资源

API modelling: Two resources with the same name

我有一个 API 建模问题需要帮助。

假设我有 Product 表示,其中包含:

Attribute Type
id string
names MultilingualName List
price decimal

MultilingualName 表示为:

Attribute Type
locale string
name string

这是为了支持多种语言,以便店主用户能够在支持多种语言的产品货架中创建产品(和 maintain/CRUD)。

我们的 POST API (/products) 可能如下所示:

{
    "id": "123abcxyz"
    "names": [
                {
                    "locale": "en-CA",
                    "name": "Pencil"
                },
                {
                    "locale": "fr-CA",
                    "name": "Crayon"
                }
             ],
    "price": 1.99
                         
}

我遇到的问题是 Product.

的基于消费者用户的 GET 端点

我想在没有 MultilingualName 语言复杂性的情况下对资源进行建模。因此,例如,GET 端点将如下所示:

Attribute Type
id string
name string
price decimal

终点将return基于用户首选语言的产品名称,这是已知的。

但显然我有问题。我现在有两种产品资源:CRUD 操作(GET、POST、PUT、DELETE)适用于维护其产品货架(具有语言复杂性)的店主,一种适用于消费者用户(仅 GET,没有语言复杂度)。

我应该如何处理这个模型?这是命名问题还是我建模不正确?

感谢您的帮助。

编辑:按照@qwerty_so 的建议添加UML。

备注:当问题有 UML 标签时提供答案(最后一部分仍然有效)

图表中存在多个问题:

  • actor 是系统外部的 classifier。因此,class 不能与演员相关联。
  • «use» 依赖项应使用虚线箭头而不是纯线箭头注明。
  • 不清楚您的 «Representation» class 和您之间的链接 »«DB table» 代表什么:它又是一个依赖关系吗?它是一个可导航的关联吗?
  • 您对一个名称有多个定义,无法消除歧义。

UML 中如何实现?

在 UML 中,在同一个命名空间中有两个同名的 class 是无效的,因为不清楚哪个 class 是什么意思。

不过,您可以调整模型并将不同的 classes 系列分开,将它们包含在不同的 packages 中,例如Database, CRUD, Consumer.

一个包定义了一个命名空间。因此,在 CRUD 包中对 Product 的所有引用都将引用相关的 CRUD class.

对于 class 不同包之间的关系,您可以使用限定名称(即包括包名称)来消除歧义,或者,如果没有冲突,可以通过将包导入另一个包来消除歧义。

这是设计您的 API 的最佳方式吗?

管理端点中的冲突名称并不理想。这很容易造成混淆。您当然可以找到解决此问题的技术解决方案,但何必呢?

为什么不根据需要保留客户端 tailoring/simplifying 数据(例如,默认使用用户的语言,除非有其他要求)?

为什么不让端点查询参数提供可选的语言代码来过滤返回的语言集?

或者为什么不使用不同的名称来称呼不同的事物呢?我在想 ProductLocalizedProductShort?

Is this a naming problem or am I approaching the modelling incorrectly?

我觉得这像是一个命名问题。

拥有多个资源,其表示来自相同的基础数据,这是完全合理的。

但是每个资源都需要有自己的标识符。机器并不特别关心标识符是什么,所以你可以使用...

/b6d5cc6a-e4b3-4bc9-90d0-723f1d8ee22a
/5952d730-d447-4537-9bf0-74cdc2f9f79a

但是人类通常使用人类可读的标识符进行更好的复制。

任何符合您当地惯例的拼写都是很好

一种可能是将观众的姓名编码到标识符本身

/storeOwner/products/123
/shopper/products/123

或者您可以选择更符合业务能力的名称

/inventory/products/123
/sales/products/123

您可以自由选择要针对哪些人进行优化(领域专家?阅读访问日志的操作员?记录 api 的技术作家?使用它的远程开发人员?等等)。