npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

apollo-server-persistgraphql

v1.0.0

Published

Use PersistGraphQL in Apollo-Server directly

Downloads

6

Readme

在 Apollo Server 中直接使用持久化查询

npm travis coverage

概述

GraphQL 能够让前端精准的获取所需的数据,但与此相伴的问题是需要在查询字符串中列出所有需要查询的字段,可能会导致查询请求过长,造成性能瓶颈。

Apollo 为解决这一问题提出了 PersistGraphQL 这一方案,为查询分配 ID 或 Hash,使客户端发送查询时只需要发送对应的 ID / Hash,从而实现压缩查询字符串长度的目的。

在 PersistGraphQL 的基础上,Apollo 又进一步推出了 apollo-link-persisted-queries,省去了 PersistGraphQL 的构建步骤,可以将服务端找不到的查询也动态的分配 Hash 值并加入到可用的查询列表中。但目前 apollo-link-persisted-queries 必须搭配 Apollo Engine 使用,而 Apollo Engine 被墙,在中国国内使用不便。

本库的目的是让无法使用 Apollo Engine 的用户也能够获得 GraphQL 持久化查询带来的好处,用户只需要对使用了 Apollo Server 的代码稍做修改即可。

兼容性

  • Apollo Server: v1.x
  • Node.js 框架: Express / Koa
  • 可手动加入白名单的文件格式: .graphql / .json(使用 PersistGraphQL 构建)

安装

npm install --save apollo-server-persistgraphql

使用

客户端直接使用 apollo-link-persisted-queries 即可。

服务端使用 Koa 的完整示例如下:

import Koa from 'koa'
import KoaRouter from 'koa-router'
import bodyParser from 'koa-bodyparser'
import { graphqlKoa } from 'apollo-server-koa'
import { PersistedGraphQL } from 'apollo-server-persistgraphql'
import schema from './schema.js'

const app = new Koa()
const router = new KoaRouter()
app.use(bodyParser())

const persistedGraphQL = new PersistedGraphQL()
const persistedOptions = ctx => persistedGraphQL.transform(
  // 用户之前的 Apollo Server 配置
  { schema: schema },
  // persistedGraphQL 配置
  { koa: ctx }
)
router.post('/graphql', graphqlKoa(persistedOptions))

app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000)

使用 Express 的完整示例如下:

import express from 'express'
import bodyParser from 'body-parser'
import { graphqlExpress } from 'apollo-server-express'
import { PersistedGraphQL } from 'apollo-server-persistgraphql'
import schema from './schema.js'

const app = express()

const persistedGraphQL = new PersistedGraphQL()
const persistedOptions = req => persistedGraphQL.transform(
  // 用户之前的 Apollo Server 配置
  { schema: schema },
  // persistedGraphQL 配置
  { express: req }
)
app.use('/graphql', bodyParser.json(), graphqlExpress(persistedOptions))
app.listen({ port: 3000 })

配置项

  • koa: 当使用 Koa 时,传入 Koa 的 context
  • express: 当使用 Express 时,传入 Express 的 request
  • onlyWhiteList: 是否只允许白名单中的查询请求,以下详述

其中,koaexpress 应至少传入一个

白名单

当用户的查询第一次发送到服务端时,由于无法找到对应的 Hash,会返回 PersistedQueryNotFound 错误,而 apollo-link-persisted-queries 发送附带 Hash 值的查询,使服务器端将查询加入缓存中。在本库中,用户可以将以 .graphql 文件形式存储的查询加入缓存,以减少一次请求的开销。

// 加入一个 .graphql 查询
persistedGraphQL.addQueryFiles(process.cwd() + '/test/test.graphql')

// 加入用 PersistGraphQL 构建出的 .json 文件
persistedGraphQL.addQueryFiles(process.cwd() + '/test/extracted_queries.json')

// 加入一个文件夹下的所有 .graphql 查询和 .json 文件
persistedGraphQL.addQueryFiles(process.cwd() + '/test/')

当用户加入查询到可用列表后,可以选择开启白名单模式,禁止可用列表之外的查询。

// 开启白名单模式
const persistedOptions = ctx => persistedGraphQL.transform(
  { schema: schema },
  {
    koa: ctx,
    onlyWhiteList: true
  }
)

// 对不同请求采用不同的模式
const persistedOptions = ctx => persistedGraphQL.transform(
  { schema: schema },
  {
    koa: ctx,
    // 对管理员不启用白名单
    onlyWhiteList: ctx.state.user !== 'admin'
  }
)

开启白名单模式后,当查询不在可用列表中时,会返回以下错误:

{
  errors: [
    { message: 'PersistedQueryNotAllowed' }
  ]
}

绑定 schema

由于本库需要在用户的 schema 上添加专用的报错信息,用户需要将 schema 进行转换并绑定。

// 在实例化 PersistedGraphQL 时,可以初始化绑定 schema
const persistedGraphQL = new PersistedGraphQL(schema)

// 在转换 Apollo Server 配置时,可以传入 schema
// 当已经传入过 schema 时,这里传入的 schema 会被忽略
const persistedOptions = ctx => persistedGraphQL.transform(
  { schema: schema },
  { koa: ctx }
)

// 可以使用此方法手动传入 schema
// 这里传入的 schema 将会覆盖之前的 schema
persistedGraphQL.updateSchema(schema)

防冲突配置

为了防止本库绑定在 schema 上的报错信息字段名与用户自定义的字段名产生冲突,可以在实例化 PersistedGraphQL 时传入报错信息使用的字段名。

// 在第二个参数传入自定义的报错字段名,默认为 PersistedQueryError
const persistedGraphQL = new PersistedGraphQL(schema, 'CustomPersistedQueryError')