在 Web 开发领域,API 是不可或缺的一部分。API 提供了一种标准化的方式,让开发者可以通过网络调用服务端的数据和功能。RESTful API 是目前最为流行的一种 API 设计模式,但是它也存在着一些不足。GraphQL 作为一种新兴的 API 技术,可以弥补 RESTful API 的不足之处。本文将介绍如何利用 GraphQL 和 RESTful API 构建更好的 API 服务。
GraphQL vs RESTful API
RESTful API 是一种基于 HTTP 协议的 API 设计模式,它使用 HTTP 动词(GET、POST、PUT、DELETE 等)来操作资源。RESTful API 遵循资源和行为的分离原则,即把 API 中的资源和行为分别处理。RESTful API 的设计原则清晰明了,易于理解和实现。
但是 RESTful API 也存在着一些不足。其中最为明显的一个问题就是过度获取资源。当我们需要获取某个资源的多个字段时,RESTful API 只能使用多次请求的方式获取所有字段的值。这种方式效率低下,而且也容易出现冗余数据。
GraphQL 是一种新兴的 API 技术,它使用一种强类型的查询语言来描述 API 的形式和数据。GraphQL 更加灵活,可以在一个请求中获取多个资源的多个字段,从而减少了网络请求次数。同时,GraphQL 还可以根据客户端需要动态决定返回哪些字段,这也减少了数据冗余。
因此,我们可以利用 GraphQL 和 RESTful API 结合起来,构建更加灵活和高效的 API 服务。
利用 GraphQL 和 RESTful API 结合
下面我们将演示如何利用 GraphQL 和 RESTful API 结合构建一个简单的 API。我们以一个电影列表应用为例,实现一个获取电影列表和电影详情的 API 接口。
RESTful API
首先我们来设计一个基于 RESTful API 的电影列表接口。我们使用 Express 框架来实现 RESTful API 的路由和逻辑:
-- -------------------- ---- ------- ----- ------- - ------------------- ----- --- - ---------- ----- ------ - - ---- -- ------ ---- --------- ------------ --------- ------ ---------- ----- ------ ---- -- ------ ---- ----------- --------- -------- ---- --------- ----- ------ ---- -- ------ ---- ---- -------- --------- ------------ ------- ----- ------ -- ------------------ ----- ---- -- - ----------------- --- ---------------------- ----- ---- -- - ----- ----- - ------------- -- ---- --- ----------------------- ---------------- --- ---------------- -- -- - ------------------- ------- -- ------------------------ ---
上面的代码实现了两个 API 接口:
/movies
:获取所有电影列表。/movies/:id
:根据 id 获取指定电影的详情。
我们可以使用 Postman 或者浏览器来测试这两个接口。例如,通过访问 http://localhost:3000/movies 可以获取所有电影的列表数据。
GraphQL
接下来我们来设计一个基于 GraphQL 的电影列表接口。我们使用 Apollo Server 来实现 GraphQL 的路由和逻辑:
-- -------------------- ---- ------- ----- - ------------- --- - - --------------------------------- ----- ------- - ------------------- ----- --- - ---------- ----- ------ - - ---- -- ------ ---- --------- ------------ --------- ------ ---------- ----- ------ ---- -- ------ ---- ----------- --------- -------- ---- --------- ----- ------ ---- -- ------ ---- ---- -------- --------- ------------ ------- ----- ------ -- ----- -------- - ---- ---- ----- - --- ---- ------ ------- --------- ------- ----- ---- - ---- ----- - ------- --------- --------- ------ ------ - -- ----- --------- - - ------ - ------- -- -- ------- ------ --- - -- -- -- ------------- -- ---- --- ---- -- -- ----- ------ - --- -------------- --------- --------- --- ------------------------ --- --- ---------------- -- -- - ------------------- ------- -- ------------------------ ---
上面的代码使用 GraphQL Schema 定义了一个 Movie 类型,包含电影的 id、title、director 和 year 四个字段。同时定义了一个 Query 类型,包含获取所有电影列表和获取指定电影详情的两个操作。
在 resolvers 中,我们实现了两个 Query 操作。在 movies 操作中,直接返回 movies 数组;在 movie 操作中,通过 id 查找指定的电影对象。
结合 RESTful API 和 GraphQL
现在我们可以将以上两个示例代码结合起来,来实现一个既能够通过 RESTful API 获取电影列表和电影详情,又能够通过 GraphQL 获取相同数据的 API。我们可以先实现一个基于 RESTful API 的电影服务类:
-- -------------------- ---- ------- ----- ----- - ---------------------- ----- ------------ - ----- ----------- - ----- --- - ----- -------------------------------------- ----- ---- - ----- ----------- ------ ----- - ----- ------------ - ----- --- - ----- -------------------------------------------- ----- ---- - ----- ----------- ------ ----- - - -------------- - -------------
通过别的代码可以调用该类的方法,来获取 Restful API 的数据。
接下来我们构建一个查询解析器,判断那个 API 被调用,从而调用指定的方法:
-- -------------------- ---- ------- ----- - -------------- - - ---------------------------------- ----- -------- ------- -------------- - ------------- - -------- ------------ - ------------------------- - ----- ----------- - ----- --- - ----- ------------------- ------ ------------- -- -- --- --------- ------ ------------ --------- --------------- ----- ----------- ---- - ----- ------------ - ----- --- - ----- ------------------------- ------ - --- ------- ------ ---------- --------- ------------- ----- --------- -- - - -------------- - ---------
最后将上述服务类和查询解析器组合到 ApolloServer 的上下文 ctx 中,这样在 resolver 中就可以直接访问服务类的方法获取 Restful API 的数据。
-- -------------------- ---- ------- ----- - ------------- --- - - --------------------------------- ----- ------- - ------------------- ----- -------- - ----------------------- ----- ------------ - --------------------------- ----- --- - ---------- ----- -------- - ---- ---- ----- - --- ---- ------ ------- --------- ------- ----- ---- - ---- ----- - ------- --------- --------- ------ ------ - -- ----- --------- - - ------ - ------- --- --- - ----------- -- -- --------------------------------- ------ --- - -- -- - ----------- -- -- ---------------------------------- -- -- ----- ------ - --- -------------- --------- ---------- ------------ -- -- -- --------- --- ----------- ------------- --- --------------- --- --- ------------------------ --- --- ---------------- -- -- - ------------------- ------- -- ------------------------ ---
上述代码利用了 ApolloServer 提供的 dataSources 功能,将服务类和查询解析器注入到 resolver 中,从而实现了 RESTful API 和 GraphQL 的结合使用。
结论
GraphQL 和 RESTful API 都是很好的 API 技术,各有优缺点。在实际项目中,我们可以根据具体需求和场景选择合适的 API 技术来使用。如果需要更加灵活和高效的数据获取方式,可以考虑使用 GraphQL;如果需要更加清晰明了的 API 设计模式,可以使用 RESTful API。同时,也可以结合使用两者的优点,构建更加完善和高效的 API 服务。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67177a0cad1e889fe221bf70