导读:本文以实践角度为各位开发者、技术人详解API中的两种重要架构风格,希望大家喜欢。
API 简介
API(应用程序编程接口的综合与)是软件与Web开发的核心支柱,为应用程序与数据库或服务器无缝通信和共享数据创建桥梁或链接。
API 架构风格有很多,有这两种风格最为流行,分别是:REST(表述性状态传输)和 GraphQL。两者均有一些优点和缺点。
本文指南将向各位介绍这些 API 架构、它们的原理、优点、缺点和用例。读完本文后,你将获得一些真实见解,可以对项目中使用的 API 架构做出更明智的决策。
我们深入研究 REST 和 GraphQL,比较它们的优缺点之后,希望能帮助更多开发者朋友做出正确的选择。
了解 REST API
REST是 REpresentational State Transfer 的缩写。
它是当今大多数服务器和网站上最常见的 API 架构风格。使用 REST 风格构建的 API 被称为 RESTful API。
RESTful API 将资源组织为统一资源标识符 (URI)。资源是 API 表示或与之交互的实体或对象。URI 区分服务器上的资源:它可以是用户资源、产品资源或图像资源,具体取决于你在后端服务器上构建的内容。
资源始终要以名词而不是动词分组。比如:
example/com/api/v1/user
而不是下面的样式:
example/com/api/v1/getauser
比如客户端想要从服务器检索用户详细信息,则客户端使用HTTP 代码向服务器发送针对用户资源的请求。
这里我们所讨论的资源就如同调用服务器上的用户数据表。
REST 的具体用例
Web服务:
REST 被广泛用于构建提供功能的 Web 服务。常见的例子有支付网关、天气服务、公共 API 等。
移动应用服务:
REST API 用于构建访问远程服务器的移动应用程序,从而可以很轻松地验证用户身份、处理事务、共享内容等。
物联网服务:
RESTful API 用于物联网设备与远程服务器通信,使服务器能够共享数据并从集中式网络接收命令。
第三方集成:
RESTful API 简化了不同系统或服务器之间的集成,使其适合数据交换、云服务和企业应用程序。
安全:
RESTful API 具有分层的 REST 系统,使其可扩展并能够在不存储客户端状态的情况下处理大量请求。
API文档:
RESTful API 允许客户端请求特定资源或该资源的表示形式(例如 JSON 或 XML),从而使其能够适应不同的客户端或最终用户的需求。
物联网服务:
RESTful API 用于物联网设备与远程服务器通信,使服务器能够共享数据并从集中式网络接收命令。
第三方集成:
RESTful API 简化了不同系统或服务器之间的集成,使其适合数据交换、云服务和企业应用程序。
安全:
RESTful API 具有分层的 REST 系统,使其可扩展并能够在不存储客户端状态的情况下处理大量请求。
API文档:
RESTful API 允许客户端请求特定资源或该资源的表示形式(例如 JSON 或 XML),从而使其能够适应不同的客户端或最终用户的需求。
第三方集成:
RESTful API 简化了不同系统或服务器之间的集成,使其适合数据交换、云服务和企业应用程序。
安全:
RESTful API 具有分层的 REST 系统,使其可扩展并能够在不存储客户端状态的情况下处理大量请求。
API文档:
RESTful API 允许客户端请求特定资源或该资源的表示形式(例如 JSON 或 XML),从而使其能够适应不同的客户端或最终用户的需求。
安全:
RESTful API 具有分层的 REST 系统,使其可扩展并能够在不存储客户端状态的情况下处理大量请求。
API文档:
RESTful API 允许客户端请求特定资源或该资源的表示形式(例如 JSON 或 XML),从而使其能够适应不同的客户端或最终用户的需求。
API文档:
RESTful API 允许客户端请求特定资源或该资源的表示形式(例如 JSON 或 XML),从而使其能够适应不同的客户端或最终用户的需求。
REST的优点
-
REST 易于理解和使用。它遵循标准的 HTTP 方法并被许多人广泛理解并使用。
-
REST 中的缓存可减少服务器负载,提高服务器和客户端的性能。
-
REST 支持众多工具和扩展库。
-
REST 端点具有清晰、可预测的 API 交互结构。
REST的缺点
-
RESTful API 依赖于 HTTP,随着时间的推移,这可能会导致与多个站点的大量连接。
-
由于客户端和服务器之间存在多次往返以及复杂的服务器端逻辑,RESTful API 可能不适合复杂的活动。
-
RESTful API 依赖于 HTTP 安全性,这可能无法满足所有安全要求;这将导致添加额外的安全层。
-
与 GraphQL 这样的查询语言不同,RESTful API 可能难以处理复杂的查询、搜索和过滤。
探索 GraphQL API
GraphQL是由Meta构建的查询架构风格语言。它提供 API 数据的架构,并让客户端请求特定数据。
它充当客户端和后端服务器或服务之间的链接。以下是我们总结的 GraphQL 的一些核心概念:
架构:
GraphQL 使用模式来定义可执行的操作或查询。该架构充当客户端和服务器之间的接口,以便获取或修改数据。
类型:
GraphQL 与 REST 一样,API 中具有多种数据类型。其中包括自定义的 String、Int、Boolean 或自定义对象类型。GraphQL 类型的每个字段都有其类型。例如,在 GraphQL 中,Book 类型的 book_name 字段是 String,publish_date 字段是 Int。不知道是否讲明白了
查询:
GraphQL 是一种查询语言,允许客户端指定他们想要从服务器获取的数据的形态和内容。客户端可以使用 GraphQL 请求查询中的特定字段,并且可以嵌套数据,服务器将使用与查询结构匹配的数据进行响应。这使客户端能够仅获取所需的数据,避免对服务器发出不必要或过多的请求。
突变:
突变是使用 GraphQL 修改数据的一种方式。与主要用于从服务器检索数据的查询,突变用于在服务器上创建、更新或删除数据。突变确保写入服务器的数据是可预测的。
订阅:
GraphQL 中的订阅支持实时更新,例如通知。客户端可以使用订阅来侦听服务器上的特定事件或操作。当这些事件或操作发生时,服务器会向订阅的客户端发送通知。
解析器:
解析器是将模式字段连接到数据源的函数,它可以根据查询获取或修改数据。解析器是模式和数据之间的桥梁,它们处理数据操作和检索的逻辑。
GraphQL 与 REST 一样,API 中具有多种数据类型。其中包括自定义的 String、Int、Boolean 或自定义对象类型。GraphQL 类型的每个字段都有其类型。例如,在 GraphQL 中,Book 类型的 book_name 字段是 String,publish_date 字段是 Int。不知道是否讲明白了
查询:
GraphQL 是一种查询语言,允许客户端指定他们想要从服务器获取的数据的形态和内容。客户端可以使用 GraphQL 请求查询中的特定字段,并且可以嵌套数据,服务器将使用与查询结构匹配的数据进行响应。这使客户端能够仅获取所需的数据,避免对服务器发出不必要或过多的请求。
突变:
突变是使用 GraphQL 修改数据的一种方式。与主要用于从服务器检索数据的查询,突变用于在服务器上创建、更新或删除数据。突变确保写入服务器的数据是可预测的。
订阅:
GraphQL 中的订阅支持实时更新,例如通知。客户端可以使用订阅来侦听服务器上的特定事件或操作。当这些事件或操作发生时,服务器会向订阅的客户端发送通知。
解析器:
解析器是将模式字段连接到数据源的函数,它可以根据查询获取或修改数据。解析器是模式和数据之间的桥梁,它们处理数据操作和检索的逻辑。
GraphQL 是一种查询语言,允许客户端指定他们想要从服务器获取的数据的形态和内容。客户端可以使用 GraphQL 请求查询中的特定字段,并且可以嵌套数据,服务器将使用与查询结构匹配的数据进行响应。这使客户端能够仅获取所需的数据,避免对服务器发出不必要或过多的请求。
突变:
突变是使用 GraphQL 修改数据的一种方式。与主要用于从服务器检索数据的查询,突变用于在服务器上创建、更新或删除数据。突变确保写入服务器的数据是可预测的。
订阅:
GraphQL 中的订阅支持实时更新,例如通知。客户端可以使用订阅来侦听服务器上的特定事件或操作。当这些事件或操作发生时,服务器会向订阅的客户端发送通知。
解析器:
解析器是将模式字段连接到数据源的函数,它可以根据查询获取或修改数据。解析器是模式和数据之间的桥梁,它们处理数据操作和检索的逻辑。
突变是使用 GraphQL 修改数据的一种方式。与主要用于从服务器检索数据的查询,突变用于在服务器上创建、更新或删除数据。突变确保写入服务器的数据是可预测的。
订阅:
GraphQL 中的订阅支持实时更新,例如通知。客户端可以使用订阅来侦听服务器上的特定事件或操作。当这些事件或操作发生时,服务器会向订阅的客户端发送通知。
解析器:
解析器是将模式字段连接到数据源的函数,它可以根据查询获取或修改数据。解析器是模式和数据之间的桥梁,它们处理数据操作和检索的逻辑。
GraphQL 中的订阅支持实时更新,例如通知。客户端可以使用订阅来侦听服务器上的特定事件或操作。当这些事件或操作发生时,服务器会向订阅的客户端发送通知。
解析器:
解析器是将模式字段连接到数据源的函数,它可以根据查询获取或修改数据。解析器是模式和数据之间的桥梁,它们处理数据操作和检索的逻辑。
解析器是将模式字段连接到数据源的函数,它可以根据查询获取或修改数据。解析器是模式和数据之间的桥梁,它们处理数据操作和检索的逻辑。
GraphQL 的特点
-
GraphQL 让客户端仅请求他们需要的数据,并将多个查询合并为一个请求,从而减少网络调用的数量和服务器上的负载。
-
GraphQL 模式易于使用和理解。它清楚地记录了 GraphQL API 可以做什么和不能做什么。
-
GraphQL 支持数据的实时更新,这使得这种 API 架构风格适合实时应用程序,例如聊天、实时推送、协作工具等。
-
GraphQL 使用 HTTP 方法(POST、GET、PUT、PATCH),但只有一个端点,这使得 API 表面变得容易。这意味着只能使用一个端点来查询资源。它不使用 URL 来指定资源;它使用模式。
-
GraphQL 使用架构上定义的关系发送复杂的查询。客户端可以查询架构以了解可用的类型、字段和 API 文档。这有助于客户开发。
GraphQL 的优点
-
GraphQL 让客户端仅请求他们需要的数据,以减少服务器端的过载。
-
GraphQL 允许客户端通过自定义请求查询来定义其响应的结构。
-
GraphQL 具有单一端点,可以简化 API 管理并减少网络请求。
-
GraphQL 架构通过订阅支持实时功能。
GraphQL 的缺点
-
在 GraphQL 中,编写复杂的查询可能很困难,并且需要对数据模式有深入了解。
-
GraphQL API 使缓存数据变得更加困难,因为它使用单点入口和 POST HTTP 方法来查询服务器。这会阻止使用 GET HTTP 缓存。
-
实施不当的 GraphQL API 可能会暴露数据,并容易受到欺骗性查询的攻击。
-
对于执行 CRUD 操作的基本 Web 应用程序或服务器,GraphQL 是一个成本更高的选择。
-
由于其语法和实现,GraphQL 对于开发人员和客户而言具有陡峭的学习曲线。
-
GraphQL 的工具和库比 REST 要少。
-
如果设计不当,GraphQL 查询可能会导致过度获取。
REST 和 GraphQL 之间的主要区别
数据检索和操作:
REST 和 GraphQL 之间的主要区别在于它们处理数据检索和操作的方式。REST 使用映射到特定资源的预定义节点,而 GraphQL 允许客户端请求特定数据并获取与请求的数据结构匹配的响应。
灵活性和效率:
REST 处理多个查询,因为每个实体都由不同的节点访问,这会导致客户端过度获取,而 GraphQL 具有可自定义的查询,有助于根据客户端需求或请求定制响应。它可以防止过度获取或不足获取。
网络请求:
REST 由于有多个结果而具有多个节点,因为每个资源都是通过单独的节点访问的,这增加了网络往返次数,尤其是在从各个节点收集相关数据时,而 GraphQL 对于所有查询只有一个节点,从而减少了网络往返次数。这有助于客户端查询针对他们所需数据的节点。
成本和维护:
REST 具有成本效益,且易于维护,因为它是一种常见的 API 架构风格,最适合业余爱好项目或小型项目,而 GraphQL 的使用和维护成本要高一些。它提供的工具较少,因此维护它将是一个新挑战。
REST 由于有多个结果而具有多个节点,因为每个资源都是通过单独的节点访问的,这增加了网络往返次数,尤其是在从各个节点收集相关数据时,而 GraphQL 对于所有查询只有一个节点,从而减少了网络往返次数。这有助于客户端查询针对他们所需数据的节点。
成本和维护:
REST 具有成本效益,且易于维护,因为它是一种常见的 API 架构风格,最适合业余爱好项目或小型项目,而 GraphQL 的使用和维护成本要高一些。它提供的工具较少,因此维护它将是一个新挑战。
REST 具有成本效益,且易于维护,因为它是一种常见的 API 架构风格,最适合业余爱好项目或小型项目,而 GraphQL 的使用和维护成本要高一些。它提供的工具较少,因此维护它将是一个新挑战。
编码示例
以下是 GraphQL 的示例(使用 Node.JS 和 Apollo Server):
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
const { ApolloServer, gql } = require('apollo-server');
// Query Schema
const typeDefs = gql`
type Query {
hello: String
}
`;
// Endpoints
const resolvers = {
Query: {
hello: () => 'Hello, World!',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
const { ApolloServer, gql } = require('apollo-server');
// Query Schema
const typeDefs = gql`
type Query {
hello: String
}
`;
// Endpoints
const resolvers = {
Query: {
hello: () => 'Hello, World!',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
这是 REST 的示例(使用 Django):
# REST VIEWS
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer
class BookList(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# REST Endpoints
from django.urls import path
from . import views
urlpatterns = [
path('books/', views.BookList.as_view(), name='book-list'),
path('books//', views.BookDetail.as_view(), name='book-detail'),
]
结论