This is a library to allow the easy creation of Relay-compliant servers using the GraphQL.js reference implementation of a GraphQL server.
A basic understanding of GraphQL and of the GraphQL.js implementation is needed to provide context for this library.
An overview of GraphQL in general is available in the README for the Specification for GraphQL.
This library is designed to work with the GraphQL.js reference implementation of a GraphQL server.
An overview of the functionality that a Relay-compliant GraphQL server should provide is in the GraphQL Relay Specification on the Relay website. That overview describes a simple set of examples that exist as tests in this repository. A good way to get started with this repository is to walk through that documentation and the corresponding tests in this library together.
Install Relay Library for GraphQL.js
npm install graphql graphql-relay
When building a schema for GraphQL.js, the provided library functions can be used to simplify the creation of Relay patterns.
Helper functions are provided for both building the GraphQL types for connections and for implementing the resolve
method for fields returning those types.
connectionArgs
returns the arguments that fields should provide when they return a connection type that supports bidirectional pagination.forwardConnectionArgs
returns the arguments that fields should provide when they return a connection type that only supports forward pagination.backwardConnectionArgs
returns the arguments that fields should provide when they return a connection type that only supports backward pagination.connectionDefinitions
returns a connectionType
and its associated edgeType
, given a node type.connectionFromArray
is a helper method that takes an array and the arguments from connectionArgs
, does pagination and filtering, and returns an object in the shape expected by a connectionType
's resolve
function.connectionFromPromisedArray
is similar to connectionFromArray
, but it takes a promise that resolves to an array, and returns a promise that resolves to the expected shape by connectionType
.cursorForObjectInConnection
is a helper method that takes an array and a member object, and returns a cursor for use in the mutation payload.offsetToCursor
takes the index of a member object in an array and returns an opaque cursor for use in the mutation payload.cursorToOffset
takes an opaque cursor (created with offsetToCursor
) and returns the corresponding array index.An example usage of these methods from the test schema:
var { connectionType: ShipConnection } = connectionDefinitions({
nodeType: shipType,
});
var factionType = new GraphQLObjectType({
name: 'Faction',
fields: () => ({
ships: {
type: ShipConnection,
args: connectionArgs,
resolve: (faction, args) =>
connectionFromArray(
faction.ships.map((id) => data.Ship[id]),
args,
),
},
}),
});
This shows adding a ships
field to the Faction
object that is a connection. It uses connectionDefinitions({nodeType: shipType})
to create the connection type, adds connectionArgs
as arguments on this function, and then implements the resolve function by passing the array of ships and the arguments to connectionFromArray
.
Helper functions are provided for both building the GraphQL types for nodes and for implementing global IDs around local IDs.
nodeDefinitions
returns the Node
interface that objects can implement, and returns the node
root field to include on the query type. To implement this, it takes a function to resolve an ID to an object, and to determine the type of a given object.toGlobalId
takes a type name and an ID specific to that type name, and returns a "global ID" that is unique among all types.fromGlobalId
takes the "global ID" created by toGlobalID
, and returns the type name and ID used to create it.globalIdField
creates the configuration for an id
field on a node.pluralIdentifyingRootField
creates a field that accepts a list of non-ID identifiers (like a username) and maps them to their corresponding objects.An example usage of these methods from the test schema:
var { nodeInterface, nodeField } = nodeDefinitions(
(globalId) => {
var { type, id } = fromGlobalId(globalId);
return data[type][id];
},
(obj) => {
return obj.ships ? factionType : shipType;
},
);
var factionType = new GraphQLObjectType({
name: 'Faction',
fields: () => ({
id: globalIdField(),
}),
interfaces: [nodeInterface],
});
var queryType = new GraphQLObjectType({
name: 'Query',
fields: () => ({
node: nodeField,
}),
});
This uses nodeDefinitions
to construct the Node
interface and the node
field; it uses fromGlobalId
to resolve the IDs passed in the implementation of the function mapping ID to object. It then uses the globalIdField
method to create the id
field on Faction
, which also ensures implements the nodeInterface
. Finally, it adds the node
field to the query type, using the nodeField
returned by nodeDefinitions
.
A helper function is provided for building mutations with single inputs and client mutation IDs.
mutationWithClientMutationId
takes a name, input fields, output fields, and a mutation method to map from the input fields to the output fields, performing the mutation along the way. It then creates and returns a field configuration that can be used as a top-level field on the mutation type.An example usage of these methods from the test schema:
var shipMutation = mutationWithClientMutationId({
name: 'IntroduceShip',
inputFields: {
shipName: {
type: new GraphQLNonNull(GraphQLString),
},
factionId: {
type: new GraphQLNonNull(GraphQLID),
},
},
outputFields: {
ship: {
type: shipType,
resolve: (payload) => data['Ship'][payload.shipId],
},
faction: {
type: factionType,
resolve: (payload) => data['Faction'][payload.factionId],
},
},
mutateAndGetPayload: ({ shipName, factionId }) => {
var newShip = {
id: getNewShipId(),
name: shipName,
};
data.Ship[newShip.id] = newShip;
data.Faction[factionId].ships.push(newShip.id);
return {
shipId: newShip.id,
factionId: factionId,
};
},
});
var mutationType = new GraphQLObjectType({
name: 'Mutation',
fields: () => ({
introduceShip: shipMutation,
}),
});
This code creates a mutation named IntroduceShip
, which takes a faction ID and a ship name as input. It outputs the Faction
and the Ship
in question. mutateAndGetPayload
then gets an object with a property for each input field, performs the mutation by constructing the new ship, then returns an object that will be resolved by the output fields.
Our mutation type then creates the introduceShip
field using the return value of mutationWithClientMutationId
.
After cloning this repo, ensure dependencies are installed by running:
npm install
This library is written in ES6 and uses Babel for ES5 transpilation and Flow for type safety. Widely consumable JavaScript can be produced by running:
npm run build
Once npm run build
has run, you may import
or require()
directly from node.
After developing, the full test suite can be evaluated by running:
npm test
We actively welcome pull requests. Learn how to contribute.
This repository is managed by EasyCLA. Project participants must sign the free (GraphQL Specification Membership agreement before making a contribution. You only need to do this one time, and it can be signed by individual contributors or their employers.
To initiate the signature process please open a PR against this repo. The EasyCLA bot will block the merge if we still need a membership agreement from you.
You can find detailed information here. If you have issues, please email operations@graphql.org.
If your company benefits from GraphQL and you would like to provide essential financial support for the systems and people that power our community, please also consider membership in the GraphQL Foundation.
Changes are tracked as GitHub releases.
graphql-relay-js is MIT licensed.
英文原版地址:https://www.howtographql.com/... 在前端使用GraphQL API,对于抽象和实现基础功能,是一个好机会。让我们考虑你在应用中可能想要的一些“基础”功能: 直接发送查询和mutation而不用构建HTTP请求 视图层集成 缓存 基于schema去校验和优化查询 当然,没有什么可以阻止你仅使用HTTP来获取你的数据,然后自己逐个处理,直到正确的信息最终显
英文原版地址:https://www.howtographql.com/... GraphQL是数据库技术吗? 不是。GraphQL经常与数据库技术混淆。这是一个误解,GraphQL是API的查询语言,而不是数据库。在这个意义上,它是数据库无关的,可以用于任何类型的数据库,甚至根本没有数据库。 GraphQL仅适用于React / Javascript开发人员? GraphQL是一种API技术,因
基于react relay graphQL的demo笔记 笔记代码详见GitHub demo介绍 demo使用React Relay GraphQL 基于GitHub GraphQL API v4实现了一个简单的topic列表查询功能,并用到了React UI组件库 Ant Design美化界面。 知识点 定义一个query,并引入片段和变量 ⚠️:用到分页功能的hook时记得引入count和cu
前言 GraphQL 的出现主要是为了要解决 Web/Mobile 端不断增加的 API 请求所衍生的问题。由于 RESTful 最大的功能在于很有效的前后端分离和建立 stateless 请求,然而 RESTful API 的资源设计上比较偏向单方面的互动,若是有着複杂资源间的关联就会出现请求次数过多,遇到不少的瓶颈。 GraphQL 初体验 GraphQL is a data query la
问题内容: 我必须从头开始一个新的(Web+本机)项目(中型应用程序)。由于存在过多的JS框架和实现,尤其是在最近几年中,我一直对我的常规堆栈有第二个疑问。 我一直在前端使用react + redux,在后端使用Node和MongoDB通过REST API进行通信。 对于这个新项目,我决定使用React-Native + Web的React Native + Node + PostgreSQL。但
温馨提示: Relay 是构建数据驱动 React 应用的 JavaScript 框架。 主要特性: 声明式:不再使用一个命令式 API 与数据存储通讯。简单的使用 GraphQL 声明你的数据需求,让 Relay 理解如何,什么时候获取你的数据。 托管:查询在视图后面,Relay 聚合查询成有效的网络请求,只获取你需要的数据。 转变:Relay 允许你使用 GraphQL mutations 在
SQLRelay 是一个持久化的数据库连接池,用来为 Unix 或者 Linux 提供数据库连接池、代理以及负载均衡的功能。 SQL Relay 的应用思路: 加速数据库驱动的基于 Web 的应用程序 增加 Web 应用程序的可扩展性 分布式的访问复制的数据库系统 对数据库访问进行节流 从不被支持的平台上访问某个数据库 可以轻松的对数据库系统进行移植 目前 SQL Reply 支持的数据库包括:
Relay Fullstack is a Relay scaffolding application that aims to help you get up and running a project without worrying about integrating tools. It comes with many modern technologies; Relay, GraphQL,
nassh-relay 为 Chromium 浏览器的 Secure Shell (hterm) 插件实现了一个中继服务器。可通过 HTTP xhr 或者 WebSockets 连接实现 SSH 通道连接。可作为一个网关来将流量引入内部网络,支持 HTTP 认证。