REST API 相同的 url - 不同的响应类型

发布于 2025-01-10 00:11:34 字数 2755 浏览 1 评论 0原文

我们正在设计一个公开的 REST API。为了符合行业标准 (https://restfulapi.net/),我们提出了以下设计问题:

  • 其中一个 API 采用以下格式 HTTP://www.mycompany.com/api/v1/items,它返回 DTO 转换为 JSON,如下所示
<前><代码>[ { id: 1, 代码: 'I1' }, { id: 2, 代码: 'I2' }, { id: 3, 代码: 'I3' } ]

除了这个 API,我们还需要支持更丰富的 DTO,如下所示:

[
    { id: 1, code: 'I1', name: 'Item1', Description: 'This is item1' }, 
    { id: 2, code: 'I2', name: 'Item2', Description: 'This is item2' }, 
    { id: 3, code: 'I3', name: 'Item3', Description: 'This is item3' }
]

您将如何塑造 URL 格式 (http:/.../..)更丰富 必须并排的响应与现有的更简单的?基本上,我们希望有像 HTTP://www.mycompany.com/api/v1/items 这样的用户友好格式,坚持标准,但同样支持多种响应格式。请记住,我们在等级上处于同一级别。 此处对资源命名进行了很好的解释。

正斜杠 (/) 字符用于 URI 的路径部分 来表示资源之间的层次关系。例如
http://api.example.com/device-management
http://api.example.com/device-management/driven-devices
http://api.example.com/device-management/driven -devices/{id}
http://api.example.com/device-management /托管设备/{id}/脚本
http://api.example. com/device-management/managed-devices/{id}/scripts/{id}

  • 以支持版本控制如何确保更深层次的向后兼容性。我们的代码是用 Java 或 C# 编写的,由我们正在开发的内部应用程序和 API 使用。目前,我们的 API 已发布由 ItemService(版本 alpha)驱动的 v1。开发团队正在开发 ItemService(版本 beta),它是前一个版本的增强版本。我应该遵循开闭实体原则吗?还有其他图案吗?
//version 1  - alpha
class ItemService {  
    public void OrderItem(Item item)
    {
        if(item.ItemId == -1) //Create if doesn't exist
        {
            CreateItem();
        }
    }
}


//version 2 - beta
class ItemService {
    public void OrderItem(Item item)
    {
        if(item.ItemId == -1) //Create if doesn't exist
        {
            CreateItem();
        } 
        //Update if exist
        else 
        {
            UpdateItem(item);
            SendEmail();
        }     
    }
}```

Bottom line, our goal is to cover multiple API versions (alpha, beta...) fully supported with a backend that is also written in version-driven manner.
 



We are in process of designing a public exposed REST API. Trying to conform to industry standards (https://restfulapi.net/) we came up to the following design questions:

  • one of the APIs is in the following format HTTP://www.mycompany.com/api/v1/items which returns DTO translated to JSON like this
[
    { id: 1, code: 'I1' },
    { id: 2, code: 'I2' }, 
    { id: 3, code: 'I3' }
]

Along with this API, we got a requirement to support richer DTO as follows

[
    { id: 1, code: 'I1', name: 'Item1', Description: 'This is item1' }, 
    { id: 2, code: 'I2', name: 'Item2', Description: 'This is item2' }, 
    { id: 3, code: 'I3', name: 'Item3', Description: 'This is item3' }
]

How would you shape URL format (http:/.../..) richer response which has to be side-by-side with the simpler existing one? Basically, we would like to have something like HTTP://www.mycompany.com/api/v1/items which is user-friendly format, stick to the standard, but again support multiple response formats. Keep in mind that we are hierarchically at the same level. Resource-naming is nicely explained here.

The forward-slash (/) character is used in the path portion of the URI
to indicate a hierarchical relationship between resources. e.g.
http://api.example.com/device-management
http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{id}
http://api.example.com/device-management/managed-devices/{id}/scripts
http://api.example.com/device-management/managed-devices/{id}/scripts/{id}

  • to support versioning how to ensure at a deeper level backward compatibility. Our code is written in Java or C# and it's consumed by internal applications and API we are developing. Right now our API has published v1 which is driven by ItemService (version alpha). Dev team is developing ItemService (version beta) which is an enriched version of the former one. Should I approach with Open-Close SOLID principle? Any other pattern?
//version 1  - alpha
class ItemService {  
    public void OrderItem(Item item)
    {
        if(item.ItemId == -1) //Create if doesn't exist
        {
            CreateItem();
        }
    }
}


//version 2 - beta
class ItemService {
    public void OrderItem(Item item)
    {
        if(item.ItemId == -1) //Create if doesn't exist
        {
            CreateItem();
        } 
        //Update if exist
        else 
        {
            UpdateItem(item);
            SendEmail();
        }     
    }
}```

Bottom line, our goal is to cover multiple API versions (alpha, beta...) fully supported with a backend that is also written in version-driven manner.
 



如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独享拥抱 2025-01-17 00:11:35

对于您的第一个问题,我会看到更丰富的 DTO 作为常规 URL 返回的默认值。如果您需要删除某些字段,则添加一个查询参数来过滤您想要的字段。
(例如 http://www.example.com/api /v1/items?fields=id,code)

如果省略查询参数,则会获取更丰富的 DTO。如果默认必须是纤薄的 DTO,也是可以的,但不那么优雅或可扩展。

对于第二个问题,我建议将每个版本的 API 开发为单独的可部署工件。然后使用版本号作为上下文(开头某处的路径的一部分)来部署它。通过这种方式,您可以修复旧版本中的错误,根据需要单独取消部署旧版本,而无需触及其他版本,还可以轻松添加新版本。

由于 REST 接口应该是无状态的,因此多个可部署项中的多个版本不应导致任何额外的问题。

For your first problem I would see the richer DTO as the default that is returned for the regular URLs. Then add a query parameter to filter for the fields you want, if you need to strip out some of the fields.
(Like http://www.example.com/api/v1/items?fields=id,code)

If the query parameter is left out, the richer DTOs are fetched. If the default has to be the slim DTO it is also possible, but not as elegant or expandable.

For the second problem I would recommend to develop each version of the API as individual deployable artifact. Then deploy it with the version number as context (piece of the path somewhere at the beginning). This way you can fix bugs in older versions, undeploy older versions on demand individually without touching the other versions, and also add new versions without any hassle.

As REST interfaces should be stateless, these multiple versions in multiple deployables should not cause any extra problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文