Skip to content
⚠️ This article was written in 2022. Some content may be outdated.

tRPC v10: Type-Safe APIs

在日常开发中,tRPC v10 类型安全 API is being used more and more frequently. This article systematically explains its usage, principles, and optimization strategies.

Quick Start

Building on this foundation, we can further optimize:

javascript
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'

const httpLink = createHttpLink({ uri: '/graphql' })
const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token')
  return { headers: { ...headers, authorization: `Bearer ${token}` } }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          users: { keyArgs: ['filter'], merge: (e, i) => ({ ...i, edges: [...(e?.edges||[]), ...i.edges] }) }
        }
      }
    }
  })
})

This pattern is very practical in large projects and can significantly reduce maintenance costs.

Internal Principles

实际项目中的用法会更复杂一些:

javascript
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'

const httpLink = createHttpLink({ uri: '/graphql' })
const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token')
  return { headers: { ...headers, authorization: `Bearer ${token}` } }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          users: { keyArgs: ['filter'], merge: (e, i) => ({ ...i, edges: [...(e?.edges||[]), ...i.edges] }) }
        }
      }
    }
  })
})

Through this approach, both the testability and scalability of the code are improved.

Business Practice

Here is a complete example:

javascript
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'

const httpLink = createHttpLink({ uri: '/graphql' })
const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token')
  return { headers: { ...headers, authorization: `Bearer ${token}` } }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          users: { keyArgs: ['filter'], merge: (e, i) => ({ ...i, edges: [...(e?.edges||[]), ...i.edges] }) }
        }
      }
    }
  })
})

Pay attention to boundary condition handling, which is critical in production.

Performance Comparison

The key lies in understanding the core logic:

javascript
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'

const httpLink = createHttpLink({ uri: '/graphql' })
const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token')
  return { headers: { ...headers, authorization: `Bearer ${token}` } }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          users: { keyArgs: ['filter'], merge: (e, i) => ({ ...i, edges: [...(e?.edges||[]), ...i.edges] }) }
        }
      }
    }
  })
})

Performance optimization should be tailored to specific scenarios; not all cases require over-optimization.

Troubleshooting

We can improve it in the following ways:

javascript
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'

const httpLink = createHttpLink({ uri: '/graphql' })
const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token')
  return { headers: { ...headers, authorization: `Bearer ${token}` } }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          users: { keyArgs: ['filter'], merge: (e, i) => ({ ...i, edges: [...(e?.edges||[]), ...i.edges] }) }
        }
      }
    }
  })
})

This approach has been running stably in production for over six months and has been practically validated.

Summary

  • In team collaboration, conventions and documentation are more important than the technology itself
  • Stay updated with the community; technical solutions need continuous iteration
  • Don't adopt new technology just for the sake of it
  • Code examples are for reference only and need to be adjusted according to your business scenario

MIT Licensed