为什么不考虑REST API版本控制中的模型? [英] Why not to consider models in REST API versioning?

查看:109
本文介绍了为什么不考虑REST API版本控制中的模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于类似的问题,有一个答案,但这也是如此

There was an answer to similar question but that was too specific to an example and doesn't answer in general.

如果未对模型进行版本控制,谁能告诉我如何处理以下情况?

Can any one please tell how to handle the below scenario if models are not versioned?

PUT /v1/users
username (string)
email (string) (required)
password (string) (required)



POST /v2/users
username (string) (required)
email (string) required
password (string) (required)

假设模型名称为 UserModel ,在v1版本中,用户名是可选的,但在V2中则是必需的。

Assuming the model name is UserModel, in v1 version username is optional but in V2 it's required.

如果使用像ajv这样的架构验证器,即使对于v1 api请求也失败,因为最新的规范/模型提到用户名是必填字段。

If we use a schema validator like ajv, it fails even for v1 api requests as the latest specification/model mentions username is required field.

每个人都有强烈的理由说不应对模型进行版本控制,但我可能会清楚地遗漏一些东西。在这种情况下,对模型进行版本控制更有意义,因为它不会轻易破坏向后兼容性。

There should be a strong reason for everyone saying models shouldn't be versioned but I might be missing something clearly. Here in this case, versioning the models makes more sense as it doesn't break backward compatibility easily.

推荐答案

您可能会感到困惑代表应用程序的模型和代表API处理的数据的模型。

You are probably confusing the models that represent the domain of your application with the models that represent the data handled by your API.

至少应该是)这些是不同的关注点,并且应解耦 >彼此之间。在添加,删除或重命名应用程序域模型中的字段时,您不想破坏API客户端。

These are (or at least should be) different concerns and should be decoupled from each other. You don't want to break your API clients when you add, remove or rename a field in your application domain model.

尽管如此,尽管您的服务层在域/持久性模型上运行,但您的API控制器应该在另一组模型上运行。

Having said that, while your service layer operates over the domain/persistence models, your API controllers should operate over a different set of models.

例如,随着您的域/持久性模型不断发展以支持新的业务需求,您可能希望创建 API模型的新版本支持这些更改。随着新版本的发布,您可能还想弃用 API的旧版本。随着客户更新代码,您可能会放弃对旧版本的支持。

As your domain/persistence models evolve to support new business requirements, for example, you may want to create new versions of your API models to support these changes. You also may want to deprecate the old versions of your API as new versions are released. As your clients update their code, you may drop the support to old versions.

出于示例目的,让我们假设您正在创建一个用于任务管理的应用程序。这就是您在域中表示任务的方式:

For example purposes, let's imagine you are creating an application for task management. And here's how you represent a task in your domain:

+----------------------+
|         Task         |
+----------------------+
| - id: Long           |
| - title: String      |
| - completed: Boolean |
+----------------------+

您的应用程序将提供一个API,以便客户可以管理其任务。

Your application will provide an API, so clients can manager their tasks.

要在您的API中创建任务,客户需要 POST 任务的JSON表示形式,带有 title 和一个布尔值,指示任务是否为完成。他们不应该提供 id 的值,因为它将由服务器生成。好东西。

To create a task in your API, the clients need to POST a JSON representation of the task, with the title and a boolean value indicating whether the task is completed or not. They are not supposed to provide a value for the id, as it will will be generated by the server. Good stuff.

有多种版本的API,包括URL和媒体类型版本控制。不过,这是一个很大的话题,在此答案中,我不会介绍每种方法的利弊。但是,出于示例目的,我将使用媒体类型版本控制:

There are different ways to version your API, which include URL and media type versioning. That's a big topic though and I won't cover the pros and cons of each approach in this answer. For example purposes, however, I'll use media type versioning:

POST /tasks HTTP/1.1
Host: example.org
Content-Type: application/vnd.foo.v1+json

{
  "title": "Send report to manager",
  "completed": false
}

在将应用程序发布到生产环境中很长时间之后,您就意识到使用表示任务状态的布尔值不是很大。并使用具有某些值的枚举,例如 NOT_STARTED STARTED COMPLETED 比布尔值更适合您的业务需求。

Long after you release your application to production, you realise that using a boolean value to represent the status of the task is not great. And using an enumeration with some values such as NOT_STARTED, STARTED and COMPLETED would suit your business requirements much better than a boolean value.

这将需要更改域模型和数据库。这就是您的域的样子:

That would require a change in your domain model and in the database as well. Here's what your domain will be like:

+----------------------+
|         Task         |
+----------------------+
| - id: Long           |
| - title: String      |
| - status: String     |
+----------------------+

因此您发布了API的新版本。现在,任务表示形式具有状态而不是完成的属性:

So you release a new version of your API. The task representation now has a status rather than a completed property:

POST /tasks HTTP/1.1
Host: example.org
Content-Type: application/vnd.foo.v2+json

{
  "title": "Send report to manager",
  "status": "NOT_STARTED"
}

那真酷。但是,不要忘记您的应用程序已经投入生产,并且您不想破坏使用旧API的客户端。

That's much cooler. But don't forget your application is already in production and you don't want to break the clients that use your old API.

因此,您将弃用端点的旧版本,但会获得一段时间的支持,以便您的客户端可以更新其代码。

So you'll deprecate the old version of your endpoint but you'll support it for a while, so your clients can update their code.

将旧任务表示形式映射到任务域模型时,应考虑以下因素:

When mapping the old task representation to the task domain model, you would consider the following:


  • 如果完成 true ,则任务 status 将为已完成

  • 如果已完成 false ,则任务 status 将为 NOT_STARTED

  • If completed is true, then the task status will be COMPLETED
  • If completed is false, then the task status will be NOT_STARTED

这篇关于为什么不考虑REST API版本控制中的模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆