例如,您运行GET请求users/9但没有id为#9的用户.哪个是最好的响应代码?
我希望通过我正在构建的分页API来处理一个奇怪的边缘情况.
像许多API一样,这个API分散了很多结果.如果您查询/ foos,您将获得100个结果(即foo#1-100),以及指向/ foos?page = 2的链接,该链接应返回foo#101-200.
不幸的是,如果在API使用者进行下一次查询之前从数据集中删除了foo#10,/ foos?page = 2将偏移100并返回foos#102-201.
对于试图吸引所有泡沫的API消费者而言,这是一个问题 - 他们不会收到foo#101.
处理这个问题的最佳做法是什么?我们希望尽可能轻量级(即避免处理API请求的会话).其他API的例子将不胜感激!
据我所知,每个资源应该只有一个规范路径.因此,在下面的示例中,优秀的URL模式是什么?
以公司的休息代表为例.在这个假设的例子中,每个公司拥有 0个或更多部门,每个部门拥有 0个或更多员工.
没有关联公司,部门就不可能存在.
没有相关部门,员工就不能存在.
现在我会找到资源模式的自然表示.
/companies 一系列公司 - 接受新公司的接受.获取整个系列./companies/{companyId}一家公司.接受GET,PUT和DELETE/companies/{companyId}/departments接受新项目的POST.(在公司内部创建一个部门.)/companies/{companyId}/departments/{departmentId}//companies/{companyId}/departments/{departmentId}/employees/companies/{companyId}/departments/{departmentId}/employees/{empId}考虑到约束,在每个部分中,我觉得如果有点深度嵌套,这是有道理的.
但是,如果我想列出(GET)所有公司的所有员工,我的困难就来了.
最合适的资源模式将映射到/employees(所有员工的集合)
这是否意味着我应该/employees/{empId}也是因为如果是这样,那么有两个URI可以获得相同的资源?
或者整个架构可能会被展平,但这意味着员工是一个嵌套的顶级对象.
在基本级别,/employees/?company={companyId}&department={deptId}返回与最深层嵌套模式完全相同的员工视图.
URL模式的最佳实践是什么,其中资源由其他资源拥有但应该可以单独查询?
更新:请参阅下面的答案,看看我做了什么.
与C#不同IEnumerable,执行管道可以根据需要执行多次,在Java中,流只能"迭代"一次.
对终端操作的任何调用都会关闭流,使其无法使用.这个"功能"消耗了很多力量.
我想这个的原因不是技术性的.这个奇怪限制背后的设计考虑是什么?
编辑:为了演示我在说什么,请考虑以下C#中的Quick-Sort实现:
IEnumerable<int> QuickSort(IEnumerable<int> ints)
{
if (!ints.Any()) {
return Enumerable.Empty<int>();
}
int pivot = ints.First();
IEnumerable<int> lt = ints.Where(i => i < pivot);
IEnumerable<int> gt = ints.Where(i => i > pivot);
return QuickSort(lt).Concat(new int[] { pivot }).Concat(QuickSort(gt));
}
Run Code Online (Sandbox Code Playgroud)
现在可以肯定的是,我并不是说这是一个很好的快速排序!然而,它是lambda表达式与流操作相结合的表达能力的一个很好的例子.
它不能用Java完成!我甚至无法询问流是否为空而不使其无法使用.
请记住,我对REST有基本的了解.假设我有这个网址:
http://api.animals.com/v1/dogs/1/
Run Code Online (Sandbox Code Playgroud)
现在,我想让服务器让狗吠.只有服务器知道如何执行此操作.假设我想让它在一个CRON工作上运行,这使得狗在永恒的剩余时间内每隔10分钟就会吠叫一次.这个电话是什么样的?我有点想这样做:
网址请求:
ACTION http://api.animals.com/v1/dogs/1/
Run Code Online (Sandbox Code Playgroud)
在请求正文中:
{"action":"bark"}
Run Code Online (Sandbox Code Playgroud)
在你为了构建我自己的HTTP方法而生气之前,请帮助我,让我更好地了解如何以RESTful方式调用服务器端方法.:)
编辑澄清
关于"树皮"方法做什么的更多澄清.以下是一些可能导致不同结构化API调用的选项:
根据文档,该方法String.valueOf(Object obj)返回:
如果参数是
null,那么一个字符串等于"null"; 否则,obj.toString()返回值.
但是当我尝试这样做时怎么样:
System.out.println("String.valueOf(null) = " + String.valueOf(null));
Run Code Online (Sandbox Code Playgroud)
它会引发NPE而不是?(如果你不相信,请亲自尝试!)
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
怎么会发生这种情况?文档对我说谎吗?这是Java中的一个主要错误吗?
以下代码抛出NullPointerException:
int num = Integer.getInteger("123");
Run Code Online (Sandbox Code Playgroud)
我的编译器是否getInteger在null上调用,因为它是静态的?这没有任何意义!
发生了什么?
我想让我的RESTful API非常可预测.决定何时使用URI而不是使用查询参数来分段数据的最佳做法是什么.
对我来说,支持分页,排序和分组的系统参数在'?'之后是有道理的.但是如果像'status'和'region'这样的字段或其他属性来分割你的收藏呢?如果那些也是查询参数,那么知道何时使用路径参数的经验法则是什么?
在设计API时我可以遵循哪些准则和最佳实践?至少,我知道API应该易于使用且灵活.不幸的是,这些术语可能相当主观,因此我正在寻找一些与良好API设计相关的具体指导原则.
如果你有一个API,并且你是一个拥有高度国际受众的英国开发人员,那么你的API应该是
setColour()
Run Code Online (Sandbox Code Playgroud)
要么
setColor()
Run Code Online (Sandbox Code Playgroud)
(用一个词作为一个简单的例子.)
英国工程师通常对他们的"正确"拼写非常防守,但可以说美国拼写在国际市场上更"标准".
我想这个问题是否重要?其他语言环境中的开发人员是否在使用GB拼写,或者通常很明显是什么意思?
应该都是美国英语吗?
api-design ×10
rest ×5
api ×3
java ×3
autoboxing ×1
http ×1
integer ×1
java-8 ×1
java-stream ×1
null ×1
overloading ×1
pagination ×1
restful-url ×1
spring-mvc ×1
url ×1