继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

REST、GraphQL、gRPC和tRPC:哪种适合你?

慕无忌1623718
关注TA
已关注
手记 218
粉丝 11
获赞 53

照片由Brendan ChurchUnsplash拍摄

如果你正在开发一个应用,你可能已经被诸如 RESTGraphQLgRPCtRPC 等术语轰炸。每一个都声称能提供更好的性能、灵活性和简洁性。但哪一个才是 正确 的选择呢?

在这篇文章中,我们将分解每个API协议,看看它们的优缺点和适用场景,让你能做出明智的选择。提示一下:没有“一招鲜吃遍天”的解决方案,但我们会帮你找到最适合你项目的选择。

REST:老可靠?

REST(表述性状态传递)是最常用的API设计风格。它以HTTP为基础,并利用标准方法如GETPOSTPUT进行操作,在客户端和服务器之间传递信息。

这里有一个简单的REST示例,使用Express.js作为服务器端和fetch作为客户端。

Express.js 服务器

    // 服务器正在端口3000上运行
    const express = require('express');
    const app = express();

    app.get('/api/users', (req, res) => {
      res.json([{ id: 1, name: 'John Doe' }]);
    });

    app.listen(3000, () => console.log('服务器正在端口3000上运行'));

    // 前端
    fetch('http://localhost:3000/api/users')
      .then(response => response.json())
      .then(data => console.log('控制台输出:', data));

好处

  • 简单,易于实现
  • 被所有现代工具很好地支持
  • 在大多数应用程序中表现良好

不足:

  • 数据抓取不当
  • 可能需要多次请求才能获取相关资源
GraphQL:灵活和掌控

GraphQL赋予客户端查询所需精确数据的能力,而且不多。不再需要多个接口,你只需要一个,并且客户端定义响应的格式。

这里有一个使用Apollo的客户端和服务器上的简单GraphQL示例:

服务器:阿波罗服务器

// 服务器(服务端)
const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type User {
    id: Int
    name: String
  }

  type Query {
    users: [User]
  }
`;

const resolvers = {
  Query: {
    users: () => [{ id: 1, name: 'John Doe' }]
  }
};

const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(`服务已启动,访问地址为 ${url}`);
});

// 客户端
import { gql, ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/',
  cache: new InMemoryCache()
});

client
  .query({
    query: gql`
      {
        users {
          id
          name
        }
      }
    `,
  })
  .then(result => console.log('查询结果:', result.data));

好的地方有:

  • 更高效的查询,仅获取你需要的数据
  • 在复杂的应用中减少网络请求
  • 非常适合前端主导的应用程序

毛病:

  • 对简单的API来说可能过于繁琐
  • 新手的学习曲线较陡
gRPC:性能和可扩展性的完美结合

当性能和低延迟至关重要时,gRPC非常理想。基于 HTTP/2,它支持双向流,非常适合高性能场景,例如微服务和实时应用。

这里有一个使用 Node.js 编写的 gRPC 服务器和客户端的例子:

使用 Node.js 的 gRPC 服务器

syntax = "proto3";

// 获取用户的请求服务
service UserService {
  // 获取用户信息
  rpc GetUser (UserRequest) returns (UserResponse);
}

// 用户请求消息,包含用户ID
message UserRequest {
  int32 id = 1;
}

// 用户响应消息,包含用户ID和名字
message UserResponse {
  int32 id = 1;
  string name = 2;
}
    // 服务端
    const grpc = require('@grpc/grpc-js');
    const protoLoader = require('@grpc/proto-loader');
    const packageDefinition = protoLoader.loadSync('user.proto');
    const userProto = grpc.loadPackageDefinition(packageDefinition).UserService;

    const server = new grpc.Server(); // 创建一个新的 gRPC 服务器实例
    server.addService(userProto.service, {
      GetUser: (call, callback) => {
        callback(null, { id: call.request.id, name: 'John Doe' }); // 这里返回的名字是固定的 'John Doe'
      },
    });

    server.bindAsync('localhost:50051', grpc.ServerCredentials.createInsecure(), () => { // 创建不安全的连接
      server.start();
    });

    // 客户端
    const grpc = require('@grpc/grpc-js');
    const protoLoader = require('@grpc/proto-loader');
    const packageDefinition = protoLoader.loadSync('user.proto');
    const userProto = grpc.loadPackageDefinition(packageDefinition).UserService;

    const client = new userProto('localhost:50051', grpc.credentials.createInsecure()); // 创建不安全的连接

    client.GetUser({ id: 1 }, (error, response) => {
      console.log(response); // 控制台输出
    });

好处:,

  • 快速高效,非常适合微服务应用。
  • 支持实时数据流处理。
  • 通信具有强类型特性。

不足

  • 相比 REST 或 GraphQL,设置起来更复杂
  • 没有基于 JSON 的 API 那么易于阅读

tRPC:既类型安全又轻量级

tRPC 让你无需模式或样板代码就能构建完全类型安全的 API,与 TypeScript 的无缝集成使其非常适合小型到中型的 TypeScript 项目。

这里有一个使用tRPC的快速示例,比如:

服务器:tRPC

     import { initTRPC } from '@trpc/server';  
    import { createHTTPServer } from '@trpc/server/adapters/standalone';  

    const t = initTRPC.create();  

    const appRouter = t.router({  
      getUser: t.procedure.query(() => {  // 查询用户信息
        return { id: 1, name: 'John Doe' };  
      }),  
    });  

    const server = createHTTPServer({ router: appRouter });  // 服务器端代码
    server.listen(3000);  

    // 客户端代码
    import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';  

    const client = createTRPCProxyClient({  
      links: [httpBatchLink({ url: 'http://localhost:3000' })],  
    });  

    // 函数 fetchUser 用于异步获取用户数据并打印到控制台
    async function fetchUser() {  
      const user = await client.getUser.query();  
      console.log(user);  
    }  

    // 调用 fetchUser 函数以获取用户数据
    fetchUser();

好处呢?

  • 端到端类型安全
  • 无需手动定义API模式
  • 对TypeScript项目几乎无额外开销

不足之处:

  • 仅适用于 TypeScript 生态圈
  • 与其它解决方案相比,相对不够成熟和普及
基于何时何地选择什么的判决

还是不确定吗?这里告诉你什么时候用哪个。

  1. REST :当你需要简单性或易用性,或者在构建传统API时。
  2. GraphQL :当你的前端应用需要灵活高效的数据查询时。
  3. gRPC :当性能至关重要时,且你在构建微服务或实时应用时。
  4. tRPC :当你在TypeScript环境中需要端到端的类型安全性时。

其实,实际上没有一种协议可以满足所有情况。您的API策略需要符合项目需求。选择要明智!

所以,你常用的 API 方法是哪个?你试过新兴的 tRPC 技术吗?下面评论区里聊聊吧!👇

直接了当 🚀

感谢您加入__In Plain English_社区!在您离开前,

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP