构建时选择哪种 HTTP 方法 Restful API

Which HTTP Method to Choose When Building Restful API

我是 node.js 的新手,我的第一个 node.js Restful API 内置在 hapi.js 框架中。所有服务所做的基本上都是数据库查询。服务示例如下:

let myservice = {
    method: "POST",
    path: "/updateRule",
    config: {
        handler: (request, reply) => {
            updateRule(request.payload)
            .then((result) => {
                reply(successResponse(request, result));
            })
            .catch((err) => reply(failResponse(request, err)).code(500));
        },
        validate: {
            payload: {
                ruleId: joi.number().required(),
                ruleName: joi.string().required(),
                ruleDesc: joi.string().required()
            }
        },
        auth: "jwt",
        tags: ["api", "a3i"]
    },
}

updateRule(input): Promise<any> {
        return new Promise((resolve, reject) => {
            let query = `select a3i.update_rule(p_rul_id := ${input.ruleId}, p_rul_name := '${input.ruleName}', p_rul_desc := '${input.ruleDesc}')`;
            postgresQuery(lbPostgres, query, (data, commit, rollback) => {
                try {
                    let count = data.rows[0].update_rule.count;
                    if (count === 1) {
                        let ruleId = data.rows[0].update_rule.result[0];
                        let payload: SuccessPayload = {
                            type: "string",
                            content: `Rule ${ruleId} has been updated`
                        };
                        commit();
                        resolve(payload);
                    } else {
                        let thisErr = new Error("No rule can be found.");
                        thisErr.name = "4003";
                        throw thisErr;
                    }
                }
                catch (err) {
                    rollback();
                    if (err.name === "4003") {
                        reject(detailError(4003, err.message));
                    } else {
                        reject(detailError(4001, err.message));
                    }
                }
            }, reject);
        });
    }

如您所见,调用服务时,它会调用数据库(查询)并更新数据库中的指定行 table。同样,我在数据库 table 中还有其他服务名为 createRule/deleteRule creating/deleting 的记录。 在我看来,服务之间的区别在于执行不同的数据库查询。我读了这个 post PUT vs. POST in REST 但看不出任何区别 POST 和 PUT 在我的例子中。

这是我的问题:

  1. 在这种情况下我应该使用什么 HTTP 方法?

  2. 大多数 Restful API 示例(例如 https://www.codementor.io/olatundegaruba/nodejs-restful-apis-in-10-minutes-q0sgsfhbd)使用相同的 URL 和不同的 HTTP 方法对相同的对象执行不同的操作"resource",在我看来通常是一个数据库table。这种架构和我实践中URL只有一个HTTP方法,只做一种操作相比有什么好处?

我知道这个问题不是指问题,也不具体。有些人可能会投反对票。但作为初学者,我真的很想知道什么是典型的 Restful API 并确保我的 API 是 "best practice"。请帮忙!

如果资源已经存在,因此您有一个指向该确切资源的特定 URI,并且您想要更新它,请使用 PUT。

如果资源尚不存在,而您想创建它,您将让服务器选择代表该新资源的 URI,然后使用 POST,POST URI 将是通用 "create new resource" URI,而不是特定资源的 URI,它将创建代表该资源的 URI。

如果调用方要创建表示新资源的资源 URI,您也可以使用 PUT 来创建新资源。在这种情况下,您只需 PUT 到那个新资源,如果具有该 URI 的资源已经存在,它将被更新,如果不存在,它将被创建。

您不必同时支持两者。您可以决定让您的 api 以您只使用其中一种的方式工作。


在您的特定情况下,对数据库中已存在的特定行的更新几乎总是 PUT,因为它已经存在,因此您正在对代表该行的特定 URI 执行 PUT。

What's the benefit of this architecture compared with my practice in which one URL only has one HTTP method and only do one type of operation?

如何展示您的 API 完全取决于您。 REST 背后的一般概念是您有几个组件:

resource identifier
data
method

在某些情况下,该方法可以包含在 GET、PUT、POST 或 DELETE 中,因此您只需要资源标识符、数据和 GET、PUT、POST 或 DELETE。

在其他情况或其他设计中,该方法比仅用 PUT 或 POST 可以表达的方法更详细,因此您实际上在 URL 中有一个方法,在这种情况下,您可能不需要区分 PUT 和 POST。

例如,一个动作可能是 "buy"。虽然您可以在 POST 中捕获它,其中 URL 的其余部分隐含了该方法,但您可能希望实际上 POST 到具有方法的 URL它:/buy 为了清楚起见,然后您可以将相同的端点前缀与其他方法(例如 /addToCart 等)一起使用......这实际上取决于您的 REST 设计中的对象以及您想要的操作浮出水面。有时,对象仅适用于 GET、PUT、POST 和 DELETE,有时,您需要 URL 中的更多信息,以了解对该资源执行的特定操作。

如果你想与 Rest 兼容,你可以只使用 PostGet。 如果你想成为 Restfull,你需要将你的方法基于 CRUD

  • 创建 -> Post
  • 读取 -> 获取
  • 更新 -> 放置或补丁
  • 删除 -> 删除

关于构建完整的 API,在相同的 URL 上使用方法可能更容易构建/理解。所有关于您的 user 的查询都将在 user url 而不是 user/getuser/adduser/update ...相同的功能,没有太多不同 URL.

构建 API 时,您需要一些日志,用于统计分析和其他内容。这样,如果您使用您的方法拆分,您可以只使用一个过滤器来记录有多少 Post 请求或 Get 请求。

事实上,您也可以仅使用 Get 请求构建一个 API。但是,使用方法和 URL 进行拆分是避免复杂 URL(或 URL 具有过多操作名称)的最佳方法,并且可以通过最简单的方法记录通过您的 [=] 的每个请求54=]

- 列表项

  • 1 级是休息

  • 2 级是 Restfull

  • 3 级是 Hateoas

您应该在 Martin Fowler 撰写的一些书籍或文章中找到更多信息

我通常做的是使用 "POST" 创建新资源,并使用 "PUT" 更新现有资源。

关于你的第二个问题,是的,大多数 API 使用相同的 URL 在相同的资源上做不同的事情。这可能是出于安全考虑,您不想在 URL 中公开您正在做的事情(例如 /delete)。此外,许多框架为资源(对象 Class)生成自动 URL,然后根据请求方法进行区分。人们只是不倾向于为这些使用自定义 URL。