关于API接口的那些事儿

作者: dreamfly 分类: 服务器 发布时间: 2023-04-01 14:25

什么是API?

您以前可能听说过“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 将以开发人员指定的格式发回响应。

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。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!