API设计:先思考再编码

API是定义应用程序接口的通用术语,换句话说,定义了用户(人或机器)如何与程序交互。在Web开发世界中,API通常是响应客户端结构化文本数据请求的网站端点集合。 Web开发人员广泛使用和讨论的另一个概念是RESTFul Web API。它由Roy Fielding定义为一种架构风格,在客户端和服务器之间提供良好的通信协议。它包含了一些约束:无状态通信,基础技术(通常为HTTP)的使用和超媒体作为应用程序状态的引擎的使用。换句话说,它提出了一些用于构建web API的模式。为了简单起见,在这篇文章中将Web API简称为API。 一个JSON值一千字 让我们看一个API响应的例子:

{
"data": [
{
"story": "Jonatas Baldin was writing a blog post.",
"created_time": "2017-15-01T00:02:57+0000",
"id": "624510964324764_1046909755418214"
},
]
}

这段JSON的数据是智能手机从Facebook API响应中收集的Facebook状态消息的示例。很漂亮,对不对? 现在想象你是Facebook的工程师,负责这个API。有天您突然决定将id字段名称更改为message_id。嗯,这个小的变化可能破坏Facebook。真的。依赖于先前定义的结构的所有设备现在都无法收集这个JSON响应,也就无法向用户显示任何内容。 好坏丑 一个坏的API设计迟早会造成各种麻烦: 1.没有一致性:一旦API增长,端点往往只是为了满足即时需求被创建。 2.难以扩展:在对端点进行故障排除时无法参考。 3.难学:消费使用数据和开发API会是一段陡峭的学习曲线。 4.性能问题:抛出未进行规划设计的API代码通常会长期产生性能瓶颈。 5.API往往是永恒的:第一次是让它就能正确的最好机会。 API是您的应用程序与其用户之间的合同。它不能突然改变,否则会导致那些已经调用它的客户端发生混乱,API不应该在没有预见性的情况下仓促建立。这就是需要设计的地方:创建一个规划或约定,用于构建对象,系统或可衡量的人类互动。 第一件事:让我们谈谈HTTP 在介绍API代码之前,让我们先看一下超文本传输协议HTTP,顾名思义,它是用于在网络上传输数据。它有一组关于客户端和服务器如何交换信息的规则。其主要组成部分有: URL:您的资源在Web上的位置,您的端点的地址。一个示例是使用http://example.org/users列出您的用户。 请求方法:客户端希望在特定端点上执行的操作。GET 用于检索资源,POST创建一个,PUT 和PATCH 来更新现有的资源,DELETE删除东西。 头部Header:包含有关客户端或服务器的信息。例如:内容类型(格式)、方法、认证令牌和其他。 正文内容body:客户端与服务器之间发送和接收的数据。JSON是事实上的标准。 状态代码:一个三位数字,用于告知请求状态。总而言之,2xx 状态表示成功,4xx意味着客户端错误,5xx意味着服务错误。 让我们看一个HTTP请求/响应示例:

Client request:
GET /users/1 HTTP/1.1
Host: www.example.org/users

Server response:
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sun, 19 Feb 2017 00:43:51 GMT

{
  "id": 1,
  "first_name": "Jonatas",
  "fast_name": "Baldin",
  "role": "Caker"
}

良好的API设计需要良好的规格 在设计API时,有一些规范可以帮助您。最常用的是使用纯JSON的Swagger、使用YAML表示法的RAML和支持markdown语法的API蓝图Blueprint。我喜欢上了后者:即使它是邻居新的酷孩子,它已经成熟足够和能够让人愉快的工作。这里会阐述为什么。 从官方网站上获得定义: API蓝图(支持markdown语法)是简单的,并且可以在API生命周期的访问每个元素。它的语法简洁而富有表现力。使用API 蓝图,您可以快速设计和创建API,或记录和测试已部署的任务关键型API。 它是一个开放源代码,专注于协作,易于学习和良好记录的规范,由Apiary创建,其核心是设计第一,周围有一些很棒的工具:从模拟服务器生成器到全功能生命周期解决方案。 除了蓝图,还有MSON(Markdown语法对象符号),它以人类可读的方式定义数据结构,不是手动编写端点的主体数据,而是在可重用对象中表示它们。 以下是您需要了解的信息: API名称,描述和元数据:关于API和蓝图版本的一些描述。 资源组:相关资源组,比如Users。 资源:定义唯一资源,它的端点和操作。 参数:在端点中用于指定动态参数,如ID或查询搜索。 响应:内容类型,HTTP状态代码和主体数据。 除此之外,蜜蜂是一个协作平台,用于创建、呈现、测试和服务您的API。他们有一个免费的公共项目计划,你可以直接用你的GitHub帐户注册,以创建自己的设计。 这里是一个蓝图代码示例:

FORMAT: 1A
HOST: http://cakes.ckl.io/

# Cakes API
Cakes is an API used to store and consume information about the most loved Cakes here at Cheesecake Labs.
Cakes是一个API,用于存储和消费关于Cheesecake Labs最受欢迎的蛋糕的信息。

# Group Cakes

## Cakes [/cakes/]

### List all Cakes [GET]

+ Response 200 (application/json)

+ Attributes (array[Cake])

# Data Structures

## Cake (object)
+ id: `1` (string, required) - The unique ID of a Cake.
+ name: `Cheesecake` (string, required) - The name of a Cake.
+ rating: `5/5` (string, optional) - The rating of a Cake.

如果您访问上面这个项目,您将看到一个漂亮的页面。真棒是:自动为每个项目创建模拟服务器是 - 见这里,看到魔法吗?不需要代码它也工作。任何有HTTP和Blueprint基本知识的人都可以创建一个模拟API,并从客户那里获得反馈。 上面的例子很简单,可以通过get获得。您可以查看蓝图教程和文档以深入了解其语法,并在此处阅读规范。此外,这是一个开源项目 - 欢迎社区的任何贡献。 恭喜!现在你掌握了设计API所需的知识。但在你开始启动你的系统之前,这里有一些小提示: 该做什么和不该做什么 这里是简单设计规则和最佳实践: 1.将端点操作视为CRUD(L)操作 我们的/cakes/端点可能有创建,读取,更新,删除和列表操作。你可以使用HTTP动词和URL来构造这些动作,例如: 列表:GET /cakes/ 创建:POST /cakes/ 阅读:GET /cakes/1/ 更新:PATCH /cakes/1/ 删除:DELETE /cakes/1/ 2.正确使用HTTP方法 GET是获得,POST是发布。如果你只是想要一个蛋糕的列表不要使用POST。 3.HTTP是有方法的,使用它们! POST /cakes/createCake 你不需要在URL中指定操作,我们已经知道POST创建一些东西,所以createCake不需要包含create字眼。 POST /cakes/ 更清晰的URL,也会告诉我们可能其他方法将按这种方式使用,如GET /cakes。 4.单数还是复数! GET /cakes应该返回一个蛋糕列表,所以GET /cake/1应该返回第一个蛋糕,对吧?很不幸的是,不行。即使它在我们的语言是有道理的,它只会用更多端点搞乱客户端和开发人员。 5.搜索,排序,限制?使用查询参数! 此功能允许您指定一些过滤列表端点,这里是一个例子: GET /cakes/?name=apple 如果实现,应该所有名称是苹果的蛋糕。 GET /cakes/?name=apple&rating=4 您也可以使用连接参数&,搜索apple和评级为4的蛋糕。 6.使用4xx返回错误。 每个人都憎恨HTTP响应状态代码是2xx,却返回一个错误的消息!使用正确的代码: 401:未经授权的访问,授权过程未正确完成。 403:禁止访问,客户端被授权,但是没有访问资源。 404:着名未找到,表示资源不可用。 7.请清楚地描述您的错误 当发生问题失败时,通知客户端发生了什么以及如何恢复。这里有一个很好的方法:

{
  "error": {
    "type": "Authentication Error",
    "details": "Authentication could not be established with the given username and password",
   }
}

大家都明白。 8.资源泪水对象类 API端点将使用资源表示进行响应。将这些资源当作对象类,然后在现实世界中代表事物。 相信我,使用设计第一的哲学将带给你更好的睡眠。这里有一些好的API优点: 与您的客户交谈:了解他们需要什么,而不是他们想要什么。没有客户端的API只是一个坏的API。 易于使用:端点,资源和输出数据应尽可能遵循相同的结构。 难以误用:如果发出了错误的请求,返回错误并提供信息。 简单是比复杂更好:简单的事情在每个方面都很容易。 在实现它之前使用你的API:创建一个模拟服务器来获得最终结果并演示。如果可以,与您未来的客户谈话并询问他们的意见。 有弹性:当发生崩溃时,告知为什么以及如何处理这种情况。 测试一切。为每个端点,方法,参数,输入和输出数据编写测试。 你的API是一种新的小语言,你必须教会其他人使用它。

原文发布于微信公众号 - Linyb极客之路(gh_c420b2cf6b47)

原文发表时间:2018-08-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

Java知识点归纳-J2EE and Web 部分

J2EE(Java2 Enterprise Edition) 刚出现时一般会用于开发企业内部的应用系统,特别是web应用,所以渐渐,有些人就会把J2EE和web...

20890
来自专栏求索之路

从零开始仿写一个抖音App——日志和埋点以及后端初步架构本项目的 github 地址:MyTikTok

拿 Java 来说:比如我们有两个服务 A、B 在两个服务器上,此时我们要在 A 上调用 B 的服务获取其上的数据 Foo。那么在 A 中可以写成 Foo f ...

57350
来自专栏程序员Gank

Android工程模块化平台的设计

首先自我介绍一下:我叫张涛,目前就职于饿了么移动技术部。可能有些朋友认识我,我之前也会在我博客【开源实验室】写一些Android相关的技术点。

10330
来自专栏Android群英传

Android工程模块化平台的设计

9140
来自专栏程序员的碎碎念

π框架之ADM分层架构

目录结构 phalapi 2.X版本与第一个版本在项目目录结构上有很大的差异,更面向自动化、国际化和流行化,学习起来更易懂。(前提是你理解了composer、命...

42880
来自专栏编程坑太多

『高级篇』docker之微服务间如何通讯(六)

在 Web 应用中处理来自客户端的请求时,通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE ...

45530
来自专栏Netkiller

分布式计划任务设计与实现

分布式计划任务设计与实现 摘要 本文主要通过分布式计划任务软件设计讲述分布式软件开发。 我的系列文档 Netkiller Architect 手札 Netk...

32650
来自专栏Java架构沉思录

Web系统权限控制如何设计

这篇文章的定位,不是宣传某个框架,仅仅之是梳理一下有关权限方面的一些想法和最近项目中的一些探索过程。 我们主要想解决一下问题。

73620
来自专栏ThoughtWorks

TW洞见 | 胡凯:Mock不是测试的银弹

开发者编写高质量测试的征途上可谓布满荆棘,数据库、中间件、不同的文件系统等复杂外部系统的存在,令开发者在编写、运行测试时觉得苦恼异常。由于外部系 统常常运行在不...

38060
来自专栏lonelydawn的前端猿区

大白话谈 Git

一、Git是什么? 定义 Git 的定义 是 一款免费、开源的版本控制系统。 免费不必多说;开源则是指将源代码公布,并允许公众查看、修改代码。 如果我们将项目每...

33260

扫码关注云+社区

领取腾讯云代金券