当前位置:Java -> 设计REST API第1部分:命名语法

设计REST API第1部分:命名语法

本文是关于如何设计出色的REST API系列文章中的第一篇。当您阅读这些文章时,您将学习如何以易于扩展、文档化和使用的方式形成API。

这些文章不会涵盖具体的实施细节(例如没有代码示例)。但是,这里提出的任何建议都可以在任何适当的框架中实现,比如Spring Boot、.Net Core MVC、NestJS等。

此外,本系列文章只涵盖JSON作为数据封装。REST API可以使用任何喜欢的数据格式,但这不在本系列的范围内。您可以从这些文章中期待到关于以JSON作为数据格式的REST API 的相关主题,并涵盖以下内容:

  1. 命名约定(本文)
  2. 可识别的设计模式
  3. 幂等性(未来文章)
  4. 分页和排序(未来文章)
  5. 搜索(未来文章)
  6. 部分更新(未来文章)
  7. 版本控制(未来文章)
  8. 身份验证(未来文章)
  9. 文档(未来文章)

以上是概述。让我们开始看命名约定,首先从命名大小写约定开始。

命名大小写约定

首先,我们将介绍在设计REST API时使用大小写的问题。您可能知道,有许多常见的命名约定,其中一些包括:

  • PascalCase
  • CamelCase
  • Snake_case

除了这些之外,还有其他命名约定存在,但在REST API中最常见的是这些。例如,您将看到Stripe的API使用snake_case,一些Amazon的API 使用PascalCase,Previsto的API使用camelCase。当您浏览许多优秀的REST API以寻找灵感时,您会发现没有一种命名约定是被广泛接受的标准。

然而 - 我必须强调camelCase在那些旨在直接在浏览器应用程序(或其他JavaScript客户端)中使用的API中提供了一些好处,因为它与JavaScript中的标准格式相同。这意味着,如果REST API在其JSON中使用camelCase,那么在JavaScript解析该JSON时,对象字段将保持相同的大小写。

示例:

想象以下数据是从服务器接收到的。

{
    "id": "anim-j95dcnjf3fjcde8nv",
    "type": "Cat",
    "name": "Garfield",
    "needsFood": true
}


然后在客户端代码中,使用这个数据就会像这样简单:

fetch('https://myshop.com/animals/anim-j95dcnjf3fjcde8nv')
  .then(response => response.json())
  .then(animal => console.log(`${animal.name} needs food: ${animal.needsFood}`));


使用camelCase可以确保对象上的字段在JavaScript解析时无需转换为另一种大小写。它们在解析为JavaScript对象时将立即处于正确的大小写。也就是说,如果REST API使用其他大小写,那么在解析JSON时进行大小写转换也是可能的,通常在客户端上这样做,但这会增加工作量。

复数还是单数

另一个经常出现的问题是在URL中为资源使用复数还是单数命名,例如 animalsanimal(在URL中反映为https://myshop.com/animalshttps://myshop.com/animal)。看起来可能是一个多余的考虑,但实际上,做出正确的决定会使API更容易进行导航。

为什么一些人更喜欢单数命名

有些人更喜欢在这里使用单数模型。他们可能会认为后端的实体是一个名为Animal的类,因此资源也应该使用资源的单数命名,他们说。因此,资源的名称定义了资源中的数据类型。这听起来像一个合理的理由,但实际上并非如此。

为什么复数命名几乎总是正确的

根据维基百科上REST的定义,资源“封装了实体(例如文件)”。因此,资源的名称不是数据类型。它是实体容器的名称 - 这些实体通常是相同类型的。想象一下您如何编写定义实体“容器”的代码片段。

// Using plural would be the correect naming 
var animals = new ArrayList<Animal>();
animals.add(new Animal());

// Using singular would not
var animal = new ArrayList<Animal>();
animal.add(new Animal());


您可以以同样的方式看待资源。它像数组、列表等一样是实体的容器,并且应该被命名为这样。这也将确保客户端中的实现可以反映其与API集成中的资源名称。以这样简化的集成为例:

class MyShopClient {
    animals() {
        return ...;
    }
}

var myshop = new MyshopClient();
myshop.animals.findAll(); // Request to https://myshop.com/animals


注意,命名自然地反映了服务器上资源的命名。像这样易于识别的模式使开发人员更容易弄清如何导航API。

可识别性

确保命名和模式易于识别应被视为API实现的质量。例如,使用不同的命名大小写约定或资源的不自然命名会使API的用户更难弄清如何使用它。但是,您可以做更多事情来确保您的API的质量。

请跟随本系列文章,我们将覆盖如何设计一个易于扩展、文档化和使用的REST API的多个方面。在下一篇文章中,我们将深入探讨如何确保API中可识别的设计模式。

推荐阅读: 20.什么是bean的自动装配?

本文链接: 设计REST API第1部分:命名语法