什么是API?
您以前可能听说过“API”一词。但它到底是什么意思,为什么它很重要?
简单来说,API(代表“应用程序编程接口”)是不同计算机程序相互通信的一种方式。把它想象成一个密码,一个程序可以用来向另一个程序询问信息或要求它做某事。
例如,您是否曾经使用过允许您使用Facebook或Google帐户登录的网站或应用程序?当你这样做时,网站或应用程序正在使用API与Facebook或谷歌的系统进行通信,并询问你是否真的是你。如果所有内容都检查出来,网站或应用程序可以让你进入。
另一个例子是天气应用程序。您可以使用手机上的天气应用来查看您所在地区的天气预报。但该应用程序本身实际上并没有创建预报 – 它使用来自天气服务的API来获取信息。该应用程序向天气服务询问您所在地区的预报,天气服务以应用程序可以理解的方式发回信息。
有各种各样的 API 可以处理各种事情——社交媒体平台、在线商店、地图和导航等等。API 使不同的程序和服务能够协同工作,这就是为什么它们在技术世界中如此重要的原因。
构建 API 时的心态?
API 非常有用,因为它们允许他们专注于构建项目所需的特定功能,而不必担心从头开始创建所有内容。通过使用 API,开发人员可以节省时间和资源,并构建更强大和创新的软件。
API 还可以使开发人员更轻松地协同工作。如果一个开发人员构建了执行特定功能的 API,则其他开发人员可以在自己的项目中使用该 API。这可以带来更快的开发、更好的协作和更成功的软件整体。
例如,开发人员可能会使用 API 将天气数据与流量数据相结合,从而创建比任何一项服务单独提供的更强大、更有用的应用。
有哪些不同类型的 API?
有几种类型的 API,包括:
-
SOAP(简单对象访问协议)API:SOAP API 用于在 Web 服务的实现中交换结构化信息。SOAP 是一种使用 XML 作为在应用程序之间交换消息的格式的协议。
-
XML-RPC API:XML-RPC 是一种远程过程调用 (RPC) 协议,它使用 XML 对其调用进行编码,并使用 HTTP 作为传输机制。它用于构建 Web 服务,并允许客户端使用 HTTP 请求与服务器通信。
-
REST(具象状态传输)API:REST 是一种使用 HTTP 作为通信协议的架构风格。RESTful API 允许客户端使用 HTTP 请求访问和操作 Web 资源,例如 GET、POST、PUT 和 DELETE。
-
JSON-RPC APIs:JSON-RPC 是一种轻量级远程过程调用 (RPC) 协议,它使用 JSON 作为格式对其调用进行编码,并使用 HTTP 作为传输机制。它用于构建 Web 服务,并允许客户端使用 HTTP 请求与服务器通信。
-
GraphQL API:GraphQL 是由 Facebook 开发的 API 查询语言。它允许客户端仅请求和接收所需的数据,使其比传统的 REST API 更高效。
-
OpenAPI(以前称为 Swagger)API:OpenAPI 是用于构建 API 的规范,它允许对 API 进行机器可读的文档。它用于描述 RESTful Web 服务,并提供一种自动生成客户端库和服务器存根的方法。
REST API 是目前最流行的 API 类型,因为它们具有简单性、灵活性和易用性。
除了基于协议的不同类型的 API 之外,根据其使用情况和有权访问它们的人员,还有不同的 API 类别或分类。下面概述了基于访问权限的一些主要 API 类型:
-
公共接口:任何人都可以访问公共 API,并可用于构建可供公众使用的应用程序。公共 API 的示例包括社交媒体 API、天气 API 和地图 API。公共 API 通常需要身份验证,但通常比其他类型的 API 更开放、更灵活。
-
合作伙伴接口: 合作伙伴 API 可供特定业务合作伙伴或客户访问,通常用于集成两个单独的系统或应用程序。合作伙伴 API 的示例包括支付网关 API 和运输 API。合作伙伴 API 通常比公共 API 更安全、更受控制,但仍需要身份验证和合作伙伴之间的一定信任级别。
-
内部接口:内部 API 在组织内用于实现不同部门或应用程序之间的通信。内部 API 的示例包括 HR API 和库存管理 API。内部 API 通常比合作伙伴和公共 API 更安全、更受控制,并且可能需要专业知识才能使用。
-
复合接口:复合 API 是通过将多个 API 组合在一起来创建更复杂的新 API 来创建的。这样做通常是为了提供比通过单个 API 提供的更自定义或更具体的服务。与其他类型的 API 相比,复合 API 需要更高级的技术技能来创建和使用。
-
B2B 接口:B2B(企业对企业)API 用于企业对企业通信和集成。它们旨在促进两个独立业务之间的通信,通常比其他类型的 API 更安全、更可控。B2B API 要求两个业务之间具有一定程度的信任,并且可能需要专业知识才能使用。
了解这两种重要的数据格式(XML 和 JSON)
如果您曾经使用过网站或应用程序,您可能遇到过XML或JSON,这是开发人员用于在不同程序之间共享信息的两种流行数据格式。在本节中,我们将解释什么是 XML 和 JSON,以及它们的重要性。
XML
XML(代表“可扩展标记语言”)是一种以结构化格式存储和共享数据的方法。它通常用于网站内容、在线表单和其他类型的需要组织且易于阅读的数据。
在 XML 文档中,数据被组织成描述数据结构的“标记”和“元素”。例如,如果您要存储有关图书的信息,则可以使用“标题”、“作者”和“出版商”等标签来组织数据。
下面是 XML 文档的外观示例:
<book>
<title>The Hitchhiker's Guide to the Galaxy</title>
<author>Douglas Adams</author>
<publisher>Pan Books</publisher>
</book>
JSON
JSON(代表“JavaScript Object Notation”)是存储和共享数据的另一种方式,通常用于Web开发。与XML一样,JSON是结构化的,但它使用不同的语法。
在 JSON 文档中,数据被组织成描述数据结构的“键值对”。例如,我们在 XML 示例中使用的相同书籍数据在 JSON 中可能如下所示:
{
"title": "The Hitchhiker's Guide to the Galaxy",
"author": "Douglas Adams",
"publisher": "Pan Books"
}
JSON 相对于 XML 的一个优点是,在 Web 应用程序中解析(或读取)通常更快、更容易,因为它是一种更轻量级的格式。
REST API 工作原理说明
那么,REST API 是如何工作的呢?简单来说,REST API 是开发人员可用于发送请求和接收数据的 URL(或“终结点”)的集合。例如,如果要构建显示天气数据的应用,则可以使用 REST API 从天气服务获取该数据。
要使用 REST API,开发人员需要使用某些参数向 API 的端点发送 HTTP 请求。然后,API 以开发人员程序可以理解的指定格式(如 JSON 或 XML)发回响应。
REST API 的特征概述
REST API 的主要功能之一是它们是“无状态的”。这意味着每个请求都独立于任何其他请求,并且 API 不会跟踪请求之间的状态。这使得 REST API 非常灵活和可扩展,并且易于在 Web 应用程序中使用。
每个请求都是独立的
在无状态体系结构中,发送到服务器的每个请求都包含完成请求所需的所有信息。这意味着服务器不会在请求之间存储任何客户端上下文。例如,假设客户端向 REST API 发出请求以检索某些数据。请求将包括所有必要的参数,例如要检索的数据类型、要应用的任何筛选器以及响应的格式。服务器处理请求并以指定格式返回请求的数据。服务器不存储有关客户端的任何信息,例如其会话状态或身份验证信息。
不维护任何客户端会话
在无状态体系结构中,服务器不会在请求之间维护任何客户端会话。这意味着每个请求都是独立处理的,服务器不依赖于任何以前的请求来处理当前请求。例如,假设客户端发送请求以更新数据库中的某些数据。请求将包括所有必要的参数,例如要更新的数据和要应用的任何约束。服务器将处理请求并更新数据库中的数据。服务器不会保留有关客户端的任何状态,例如客户端之前更新了哪些数据。
可扩展性和可靠性
无状态原则使 REST API 具有高度可伸缩性和可靠性。由于每个请求都是独立的,因此服务器不需要在请求之间维护任何客户端状态或上下文。这意味着服务器可以独立并行处理每个请求,从而提高性能和可伸缩性。此外,由于每个请求都是独立的,因此如果一个请求失败,则不会影响其他请求的处理。这使得 REST API 更加可靠和容错。
更多 REST API 的特征
是它们使用一组标准的 HTTP 方法来描述可以对 API 的资源执行的操作。这些方法包括“GET”(检索数据)、“POST”(创建新数据)、“PUT”(更新现有数据)和“DELETE”(删除数据)。
下面是一个简单的 REST API 请求的示例,使用天气应用的示例:
GET https://api.weather.com/forecast?zip=90210&appid=YOUR_API_KEY
在此示例中,开发人员向 API 的终结点发送“GET”请求,以检索特定邮政编码的天气预报。API 将以开发人员指定的格式发回响应。
JavaScript 示例:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data));
python 示例:
import requests
response = requests.get('https://api.example.com/data')
data = response.json()
print(data)
在这些示例中,我们使用 GET 方法从 REST API 终结点检索数据。在 JavaScript 中,我们使用 fetch 函数发出请求,然后将响应解析为 JSON。在 Python 中,我们使用请求库来发出请求,然后将响应解析为 JSON。
使用 POST 方法创建新数据:
JavaScript 示例:
fetch('https://api.example.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John', age: 25 })
})
.then(response => response.json())
.then(data => console.log(data));
Python 示例
import requests
response = requests.post('https://api.example.com/data', json={'name': 'John', 'age': 25})
data = response.json()
print(data)
在这些示例中,我们使用 POST 方法在 REST API 中创建新数据。在 JavaScript 中,我们再次使用 fetch 函数,但这次我们指定要使用 POST 方法并在请求正文中发送 JSON 数据。在 Python 中,我们使用请求库发出 POST 请求并在请求正文中发送 JSON 数据。
使用 PUT 方法更新现有数据:
JavaScript 示例:
fetch('https://api.example.com/data/123', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John', age: 26 })
})
.then(response => response.json())
.then(data => console.log(data));
python put 示例:
import requests
response = requests.put('https://api.example.com/data/123', json={'name': 'John', 'age': 26})
data = response.json()
print(data)
在这些示例中,我们使用 PUT 方法来更新 REST API 中的现有数据。在 JavaScript 中,我们再次使用 fetch 函数,但这次我们指定要使用 PUT 方法并在请求正文中发送 JSON 数据。在 Python 中,我们使用请求库发出 PUT 请求并在请求正文中发送 JSON 数据。
使用 DELETE 方法删除数据:
JavaScript 示例:
fetch('https://api.example.com/data/123', {
method: 'DELETE'
})
.then(response => console.log('Data deleted'));
Pytho 示例:
import requests
response = requests.delete('https://api.example.com/data/123')
print('Data deleted')
在这些示例中,我们使用 DELETE 方法从 REST API 中删除数据。
在 JavaScript 中,我们再次使用 fetch 函数,但这次我们指定要使用 DELETE 方法。在 Python 中,我们使用请求库来发出 DELETE 请求。
请注意,在这两种情况下,我们都不希望收到包含数据的响应,因此我们只是将消息记录到控制台。
如何保护 REST API?
如果要构建 REST API,请务必确保它免受潜在攻击。
使用HTTPS
要保护 REST API,您可以做的最重要的事情之一就是使用 HTTPS。HTTPS 是一种加密通过互联网发送的数据的方式,使攻击者更难拦截和读取数据。要使用 HTTPS,您需要从受信任的证书颁发机构获取 SSL/TLS 证书。
下面是如何使用 Express 框架在 Node.js 应用程序中启用 HTTPS 的示例:
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
const options = {
key: fs.readFileSync('/path/to/private.key'),
cert: fs.readFileSync('/path/to/certificate.crt')
};
app.get('/', (req, res) => {
res.send('Hello, world!');
});
https.createServer(options, app).listen(443);
实施身份验证和授权
保护 REST API 的另一个重要方面是实现身份验证和授权。身份验证是验证用户身份的过程,而授权是确定允许用户执行的操作的过程。
实现身份验证和授权的一种方法是使用令牌。当用户登录到您的应用程序时,您可以生成表示该用户会话的令牌。然后,可以将令牌与每个请求一起发送到 API,API 可以使用令牌来验证用户的身份和权限。
下面是如何使用 JSON Web 令牌 (JWT) 库在 Node.js 应用程序中实现基于令牌的身份验证的示例:
const jwt = require('jsonwebtoken');
const express = require('express');
const app = express();
app.post('/login', (req, res) => {
// verify user credentials
const user = { id: 1, name: 'John Doe' };
const token = jwt.sign(user, 'secret');
res.json({ token });
});
app.get('/protected', (req, res) => {
// verify token
const authHeader = req.headers.authorization;
if (!authHeader) return res.sendStatus(401);
const token = authHeader.split(' ')[1];
jwt.verify(token, 'secret', (err, user) => {
if (err) return res.sendStatus(403);
res.send(`Welcome, ${user.name}!`);
});
});
app.listen(3000);
在此示例中,/login 终结点用于在用户登录时生成 JWT 令牌。然后,令牌与请求一起发送到 /protected 终结点,该终结点验证令牌并在用户获得授权时发送响应。
限制访问和使用速率限制
若要进一步保护 REST API,可以限制访问和使用速率限制。可以通过限制允许哪些 IP 地址或域访问 API 来实现访问限制。速率限制可用于防止用户在短时间内发出过多请求,这有助于防止 DDoS 攻击。
下面是如何使用表达式速率限制库在 Node.js 应用程序中实现速率限制的示例:
const rateLimit = require('express-rate-limit');
const express = require('express');
const app = express();
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100, // limit each
});
app.use(limiter);
app.get('/', (req, res) => {
res.send('Hello, world!');
});
app.listen(3000);
在此示例中,表达式速率限制中间件用于将请求数限制为每分钟 100 个。如果用户超过此限制,他们将收到“429 请求过多”响应。
验证用户输入
最后,验证用户输入以防止 SQL 注入和跨站点脚本 (XSS) 等攻击非常重要。在数据库查询中使用用户输入或以 HTML 格式呈现用户输入之前,请务必对其进行清理和验证。
下面是如何使用验证程序.js库在 Node.js 应用程序中验证用户输入的示例:
const validator = require('validator');
const express = require('express');
const app = express();
app.post('/user', (req, res) => {
const { name, email, password } = req.body;
if (!validator.isEmail(email)) {
return res.status(400).json({ message: 'Invalid email address' });
}
// create new user in database
res.json({ message: 'User created' });
});
app.listen(3000);
在此示例中,验证程序.js库用于在数据库中创建新用户之前验证电子邮件地址。如果电子邮件地址无效,API 将返回 400 错误请求响应。
如何编写 API 文档?
构建 API 时,请务必提供清晰全面的文档,使开发人员能够轻松理解和使用您的 API。在本节中,我们将介绍 API 文档的一些最佳实践。
保持简单
API 文档的第一条规则是保持简单。开发人员希望能够快速了解您的 API 的工作原理以及如何使用它。使用清晰简洁的语言,避免使用技术术语或过于复杂的概念。
下面是天气 API 的简单明了的 API 文档示例:
/**
* @api {get} /weather Request weather information
* @apiName GetWeather
* @apiGroup Weather
*
* @apiParam {String} location The name of the location you want the weather for (required).
* @apiParam {String="metric","imperial"} [units="metric"] The units to display the weather in (optional).
*
* @apiSuccess {String} location The name of the location.
* @apiSuccess {Number} temperature The temperature in the specified units.
* @apiSuccess {String} conditions The current weather conditions.
*
* @apiSuccessExample Success-Response:
* HTTP/1.1 200 OK
* {
* "location": "London",
* "temperature": 10,
* "conditions": "Cloudy"
* }
*/
```
下面是包含日历 API 示例的 API 文档示例:
/**
- @api {get} /events Request events for a specified period
- @apiName GetEvents
- @apiGroup Calendar
- @apiParam {String} start The start date of the events to retrieve, in ISO format (YYYY-MM-DD) (required).
- @apiParam {String} end The end date of the events to retrieve, in ISO format (YYYY-MM-DD) (required).
- @apiParam {String="public","private"} [type] The type of events to retrieve (optional).
- @apiSuccess {Object[]} events An array of events.
- @apiSuccess {Number} events.id The ID of the event.
- @apiSuccess {String} events.title The title of the event.
- @apiSuccess {String} events.start The start time of the event, in ISO format.
- @apiSuccess {String} events.end The end time of the event, in ISO format.
- @apiSuccess {String} events.location The location of the event.
- @apiSuccessExample Success-Response:
- HTTP/1.1 200 OK
- [
- {
- "id": 123,
- "title": "Company Meeting",
- "start": "2022-03-15T10:00:00",
- "end": "2022-03-15T11:00:00",
- "location": "Office"
- },
- {
- "id": 456,
- "title": "Project Deadline",
- "start": "2022-03-25T12:00:00",
- "end": "2022-03-25T18:00:00",
- "location": "Remote"
- }
- ]
*/
使用 Flask 构建 API 的示例,Flask 是用于构建 API 的流行 Web 框架。
假设我们正在为一个简单的电子商务应用程序构建 API,第一步是定义 API 要求。对于我们的电子商务应用程序,我们可能需要支持以下功能:
-
检索所有产品的列表
-
检索特定产品的详细信息
-
创建新产品
-
更新现有产品
-
删除产品
定义 API 要求后,下一步将是选择编程语言和框架。在本例中,我们将使用 Python 和 Flask。
要开始构建 API,我们需要使用 pip 安装 Flask:
pip install flask
接下来,我们将创建一个新的 Flask 应用程序并定义 API 的端点。下面是此代码的外观示例:
from flask import Flask, jsonify, request
app = Flask(__name__)
# Define the product data
products = [
{'id': 1, 'name': 'Product 1', 'price': 10.00},
{'id': 2, 'name': 'Product 2', 'price': 20.00},
{'id': 3, 'name': 'Product 3', 'price': 30.00}
]
# Define the endpoints
@app.route('/products', methods=['GET'])
def get_all_products():
return jsonify({'products': products})
@app.route('/products/<int:id>', methods=['GET'])
def get_product(id):
for product in products:
if product['id'] == id:
return jsonify({'product': product})
return jsonify({'message': 'Product not found'})
@app.route('/products', methods=['POST'])
def create_product():
product = request.get_json()
products.append(product)
return jsonify({'message': 'Product created successfully'})
@app.route('/products/<int:id>', methods=['PUT'])
def update_product(id):
for product in products:
if product['id'] == id:
product['name'] = request.json['name']
product['price'] = request.json['price']
return jsonify({'message': 'Product updated successfully'})
return jsonify({'message': 'Product not found'})
@app.route('/products/<int:id>', methods=['DELETE'])
def delete_product(id):
for product in products:
if product['id'] == id:
products.remove(product)
return jsonify({'message': 'Product deleted successfully'})
return jsonify({'message': 'Product not found'})
在此示例中,我们为 API 定义了五个终结点:
/products、
/products/<int:id>、
/products、
/products/<int:id> 和 /products/<int:id>。
这些终结点对应于我们之前定义的功能。
为了测试 API,我们可以使用像 Postman 这样的工具向 API 发送请求并验证响应。例如,要检索所有产品的列表,我们可以向 /products 端点发送 GET 请求。下面是一个示例,说明这在 Postman 中的外观:
“http://localhost:5000/products”
来自 API 的响应将是:
{
"products": [
{
"id": 1,
"name": "Product 1",
"price": 10.0
},
{
"id": 2,
"name": "Product 2",
"price": 20.0
},
{
"id": 3,
"name": "Product 3",
"price": 30.0
}
]
}
API 按预期工作后,下一步就是记录 API。这可能涉及创建描述 API 功能的 API 文档,以及创建如何使用 API 的示例。对于我们的电子商务 API,文档可能如下所示:
电子商务 API 提供以下功能:
GET /products:检索所有产品的列表
GET /products/{id}:检索特定产品的详细信息
POST /products :发布/产品:创建新产品
PUT /products/{id}:更新现有产品
DELETE /products/{id}:删除产品
所有请求和响应都应采用 JSON 格式。
若要检索所有产品的列表,请向 /products 发送 GET 请求。响应将是一个包含产品数组的 JSON 对象:
{
"products": [
{
"id": 1,
"name": "Product 1",
"price": 10.0
},
{
"id": 2,
"name": "Product 2",
"price": 20.0
},
{
"id": 3,
"name": "Product 3",
"price": 30.0
}
]
}
检索特定产品的详细信息
要检索特定产品的详细信息,请向 /products/{id} 发送 GET 请求,其中 {id} 是产品的 ID。响应将是一个包含产品详细信息的 JSON 对象:
{
"product": {
"id": 1,
"name": "Product 1",
"price": 10.0
}
}
创建新产品
要创建新产品,请使用包含产品详细信息的 JSON 对象向 /products 发送 POST 请求:
{
"id": 4,
"name": "Product 4",
"price": 40.0
}
#Response:
{
"message": "Product created successfully"
}
更新现有产品
要更新现有产品,请向 /products/{id} 发送 PUT 请求,其中 {id} 是产品的 ID,其中包含包含产品更新详细信息的 JSON 对象:
{
"name": "New Product Name",
"price": 15.0
}
#Response:
{
"message": "Product updated successfully"
}
删除产品
要删除产品,请向 /products/{id} 发送 DELETE 请求,其中 {id} 是产品的 ID:
#Response:
{
"message": "Product deleted successfully"
}
API 文档可以让其他开发人员更轻松地使用您的 API,并确保 API 易于理解。
结论
API 已成为现代软件开发的重要组成部分,使应用程序能够相互通信和共享数据。在本文中,我们探讨了 API 的基础知识,包括它们是什么、它们是如何工作的,以及为什么它们对开发人员很重要。
我们首先定义了 API 并检查了它们的核心原则,包括无状态和统一接口。
接下来,我们探讨了与构建和使用 API 相关的一些常见挑战,例如安全性和文档。我们讨论了保护 API 的最佳实践,包括身份验证的使用,并研究了良好文档在帮助其他开发人员理解和使用您的 API 方面的重要性。
最后,我们将我们的知识付诸实践,通过使用 Flask Web 框架构建一个简单的电子商务 API,并使用示例和示例代码记录 API。按照本文中的步骤操作,您现在应该对 API 有深入的了解,并能够在自己的项目中开始使用和构建简单的 API。