我从 Apollo Client 迁移到了 Vercel SWR 和 Prisma graphql-request...你也可以!

2025-06-08

我从 Apollo Client 迁移到了 Vercel SWR 和 Prisma graphql-request...你也可以!

GraphQL 请求其实就是向 GraphQL 端点发出的 POST 请求。为什么需要这么大的成本来设置 Apollo 客户端呢?

我已经厌倦了设置 Apollo Client,而且当它与 Vercel Next.js 的 Now 搭配使用时,简直是头痛不已。需要做出一些让步。

来看看Prisma 的 graphql-request(用于发起实际的 POST 请求)和Vercel SWR (用于状态缓存)。通过移除 Apollo 客户端,我成功地从 JavaScript 构建中节省了 40 kB。瞧瞧我避开的这个Apollo 地狱,看看这个Next.js 吧

好的,好的,您来这里是为了了解如何迁移的示例。它们就在这里!

没有变量的基本查询

使用 Apollo 客户端

// with Apollo Client:
import { gql, useQuery } from '@apollo/client';

const PAID_JOBS_QUERY = gql`
  query paidJobPosts {
    jobPosts {
      id
    }
  }
`;
const yourReactComponent = () => {
  const { data, loading, error } = useQuery(PAID_JOBS_QUERY); 
}

使用 Vercel SWR 和 Prisma graphql-request

// with SWR and graphql-request
import { request } from 'graphql-request';
import useSWR from 'swr';

// the comment below gives us VSCode syntax highlighting!
const PAID_JOBS_QUERY = /* GraphQL */ `
  query paidJobPosts {
    jobPosts {
      id
    }
  }
`;
const yourReactComponent = () => {
  const { data, error } = useSWR(PAID_JOBS_QUERY, (query) => request('/api', query));
  const loading = !data;
};

带变量的基本查询

使用 Apollo 客户端

// with Apollo Client:
import { gql, useQuery } from '@apollo/client';
const JOB_POST_BY_ID_QUERY = gql`
  query jobPostByIdQuery($id: String) {
    jobPost(where: { id: $id }) {
      id
    }
  }
`;
const yourReactComponent = ({ id }) => {
  const { data, loading, error } = useQuery(JOB_POST_BY_ID_QUERY, { variables: { id } });
};

使用 Vercel SWR 和 Prisma graphql-request

// with SWR and graphql-request
import { request } from 'graphql-request';
import useSWR from 'swr';

// the comment below gives us VSCode syntax highlighting!
const JOB_POST_BY_ID_QUERY = /* GraphQL */ `
  query jobPostByIdQuery($id: String) {
    jobPost(where: { id: $id }) {
      id
    }
  }
`;
const yourReactComponent = ({ id }) => {
  const { data, error } = useSWR([JOB_POST_BY_ID_QUERY, id], (query, id) => request('/api', query, { id }));
  const loading = !data;
};

变量的基本变异

使用 Apollo 客户端

// with Apollo Client:
import { gql, useMutation } from '@apollo/client';

const CREATE_JOB_POST_MUTATION = gql`
  mutation createJobPostMutation($jobName: String!) {
    createOneJobPost(jobName: $jobName) {
      id
    }
  }
`;
const yourReactComponent = () => {
  const [createJobPost] = useMutation(CREATE_JOB_POST_MUTATION);

  const submitJobPost = async (jobName) => {
    const { data } = await createJobPost({ variables: { jobName } });
    // do something with job post
  };
};

使用 Prisma graphql-request

// with SWR and graphql-request
import { request } from 'graphql-request';

const CREATE_JOB_POST_MUTATION = /* GraphQL */ `
  mutation createJobPostMutation($jobName: String!) {
    createOneJobPost(jobName: $jobName) {
      id
    }
  }
`;
const createJobPost = (variables) => {
  return request('/api', CREATE_JOB_POST_MUTATION, variables);
};

const yourReactComponent = ({ id }) => {
  const submitJobPost = async (jobName) => {
    const data = await createJobPost({ jobName });
    // do something with data
  };
};

缓存刷新突变

使用 Apollo 客户端

// with Apollo Client:
import { gql, useMutation, useQuery } from '@apollo/client';

const ME_QUERY = gql`
  query MeQuery {
    me {
      id
    }
  }
`;
const someReactComponentThatFetchesMe = () => {
  const { data } = useQuery(ME_QUERY);
};

const SIGNIN_MUTATION = gql`
  mutation signInMutation($email: String!, password: String!) {
    signin(email: $email, password: $password) {
      id
    }
  }
`;
const yourReactComponent = () => {
  const [signin] = useMutation(SIGNIN_MUTATION);

  const submit = (email, password) => {
    signin({ variables: { email, password }, refetchQueries: [{ query: ME_QUERY }] });
  };
};

使用 Vercel SWR 和 Prisma graphql-request

// with SWR and graphql-request
import { request } from 'graphql-request';
import useSWR from 'swr';

const ME_QUERY = /* GraphQL */ `
  query MeQuery {
    me {
      id
    }
  }
`;
const someReactComponentThatFetchesMe = () => {
  const { data } = useSWR(ME_QUERY); // the key to this value in cache is the value fo ME_QUERY
};

const SIGNIN_MUTATION = /* GraphQL */ `
  mutation signInMutation($email: String!, password: String!) {
    signin(email: $email, password: $password) {
      id
    }
  }
`;
const signIn = (variables) => {
  return request('/api', SIGNIN_MUTATION, variables);
};

const yourReactComponent = () => {
  const { mutate } = useSWR(ME_QUERY); // the mutate function will do the refetching for us

  const submit = async (email, password) => {
    await signin({ email, password });
    mutate(); // call mutate here to refetch Me after signin
  };
};
链接已链接 https://dev.to/aryanjnyc/i-migrated-away-from-apollo-client-to-vercel-swr-and-prisma-graphql-request-and-you-can-too-245b
PREV
使用 NestJS 搭建 Node.js 服务器,包含 TypeScript 和 GraphQL
NEXT
嘲弄敏捷 嘲笑方法论 严肃地说 快餐管道 完美的美食 那又怎样?