{"id":13499244,"url":"https://github.com/graphql/graphql-relay-js","last_synced_at":"2025-05-14T01:03:15.648Z","repository":{"id":35925342,"uuid":"40213252","full_name":"graphql/graphql-relay-js","owner":"graphql","description":"A library to help construct a graphql-js server supporting react-relay.","archived":false,"fork":false,"pushed_at":"2024-07-11T18:25:20.000Z","size":1327,"stargazers_count":1542,"open_issues_count":25,"forks_count":180,"subscribers_count":72,"default_branch":"main","last_synced_at":"2025-04-02T01:09:39.670Z","etag":null,"topics":["graphql","relay"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/graphql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-04T23:03:39.000Z","updated_at":"2025-04-01T20:54:18.000Z","dependencies_parsed_at":"2024-03-27T18:38:27.954Z","dependency_job_id":"a170dd2e-1327-453a-828e-966444002a02","html_url":"https://github.com/graphql/graphql-relay-js","commit_stats":{"total_commits":275,"total_committers":55,"mean_commits":5.0,"dds":0.6472727272727272,"last_synced_commit":"6600e95a3cfebebfc40e746425fe278c8aa9da7b"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql%2Fgraphql-relay-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql%2Fgraphql-relay-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql%2Fgraphql-relay-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql%2Fgraphql-relay-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/graphql","download_url":"https://codeload.github.com/graphql/graphql-relay-js/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247962460,"owners_count":21024862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","relay"],"created_at":"2024-07-31T22:00:31.283Z","updated_at":"2025-04-09T02:10:56.011Z","avatar_url":"https://github.com/graphql.png","language":"TypeScript","readme":"# Relay Library for GraphQL.js\n\nThis is a library to allow the easy creation of Relay-compliant servers using the [GraphQL.js](https://github.com/graphql/graphql-js) reference implementation of a GraphQL server.\n\n[![Build Status](https://github.com/graphql/graphql-relay-js/workflows/CI/badge.svg?branch=main)](https://github.com/graphql/graphql-relay-js/actions?query=branch%3Amain)\n[![Coverage Status](https://codecov.io/gh/graphql/graphql-relay-js/branch/master/graph/badge.svg)](https://codecov.io/gh/graphql/graphql-relay-js)\n\n## Getting Started\n\nA basic understanding of GraphQL and of the GraphQL.js implementation is needed to provide context for this library.\n\nAn overview of GraphQL in general is available in the [README](https://github.com/graphql/graphql-spec/blob/master/README.md) for the [Specification for GraphQL](https://github.com/graphql/graphql-spec).\n\nThis library is designed to work with the [GraphQL.js](https://github.com/graphql/graphql-js) reference implementation of a GraphQL server.\n\nAn overview of the functionality that a Relay-compliant GraphQL server should provide is in the [GraphQL Relay Specification](https://relay.dev/docs/guides/graphql-server-specification/) on the [Relay website](https://relay.dev/). That overview describes a simple set of examples that exist as [tests](src/__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.\n\n## Using Relay Library for GraphQL.js\n\nInstall Relay Library for GraphQL.js\n\n```sh\nnpm install graphql graphql-relay\n```\n\nWhen building a schema for [GraphQL.js](https://github.com/graphql/graphql-js), the provided library functions can be used to simplify the creation of Relay patterns.\n\n### Connections\n\nHelper functions are provided for both building the GraphQL types for connections and for implementing the `resolve` method for fields returning those types.\n\n- `connectionArgs` returns the arguments that fields should provide when they return a connection type that supports bidirectional pagination.\n- `forwardConnectionArgs` returns the arguments that fields should provide when they return a connection type that only supports forward pagination.\n- `backwardConnectionArgs` returns the arguments that fields should provide when they return a connection type that only supports backward pagination.\n- `connectionDefinitions` returns a `connectionType` and its associated `edgeType`, given a node type.\n- `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.\n- `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`.\n- `cursorForObjectInConnection` is a helper method that takes an array and a member object, and returns a cursor for use in the mutation payload.\n- `offsetToCursor` takes the index of a member object in an array and returns an opaque cursor for use in the mutation payload.\n- `cursorToOffset` takes an opaque cursor (created with `offsetToCursor`) and returns the corresponding array index.\n\nAn example usage of these methods from the [test schema](src/__tests__/starWarsSchema.ts):\n\n```js\nvar { connectionType: ShipConnection } = connectionDefinitions({\n  nodeType: shipType,\n});\nvar factionType = new GraphQLObjectType({\n  name: 'Faction',\n  fields: () =\u003e ({\n    ships: {\n      type: ShipConnection,\n      args: connectionArgs,\n      resolve: (faction, args) =\u003e\n        connectionFromArray(\n          faction.ships.map((id) =\u003e data.Ship[id]),\n          args,\n        ),\n    },\n  }),\n});\n```\n\nThis 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`.\n\n### Object Identification\n\nHelper functions are provided for both building the GraphQL types for nodes and for implementing global IDs around local IDs.\n\n- `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.\n- `toGlobalId` takes a type name and an ID specific to that type name, and returns a \"global ID\" that is unique among all types.\n- `fromGlobalId` takes the \"global ID\" created by `toGlobalID`, and returns the type name and ID used to create it.\n- `globalIdField` creates the configuration for an `id` field on a node.\n- `pluralIdentifyingRootField` creates a field that accepts a list of non-ID identifiers (like a username) and maps them to their corresponding objects.\n\nAn example usage of these methods from the [test schema](src/__tests__/starWarsSchema.ts):\n\n```js\nvar { nodeInterface, nodeField } = nodeDefinitions(\n  (globalId) =\u003e {\n    var { type, id } = fromGlobalId(globalId);\n    return data[type][id];\n  },\n  (obj) =\u003e {\n    return obj.ships ? factionType : shipType;\n  },\n);\n\nvar factionType = new GraphQLObjectType({\n  name: 'Faction',\n  fields: () =\u003e ({\n    id: globalIdField(),\n  }),\n  interfaces: [nodeInterface],\n});\n\nvar queryType = new GraphQLObjectType({\n  name: 'Query',\n  fields: () =\u003e ({\n    node: nodeField,\n  }),\n});\n```\n\nThis 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`.\n\n### Mutations\n\nA helper function is provided for building mutations with single inputs and client mutation IDs.\n\n- `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.\n\nAn example usage of these methods from the [test schema](src/__tests__/starWarsSchema.ts):\n\n```js\nvar shipMutation = mutationWithClientMutationId({\n  name: 'IntroduceShip',\n  inputFields: {\n    shipName: {\n      type: new GraphQLNonNull(GraphQLString),\n    },\n    factionId: {\n      type: new GraphQLNonNull(GraphQLID),\n    },\n  },\n  outputFields: {\n    ship: {\n      type: shipType,\n      resolve: (payload) =\u003e data['Ship'][payload.shipId],\n    },\n    faction: {\n      type: factionType,\n      resolve: (payload) =\u003e data['Faction'][payload.factionId],\n    },\n  },\n  mutateAndGetPayload: ({ shipName, factionId }) =\u003e {\n    var newShip = {\n      id: getNewShipId(),\n      name: shipName,\n    };\n    data.Ship[newShip.id] = newShip;\n    data.Faction[factionId].ships.push(newShip.id);\n    return {\n      shipId: newShip.id,\n      factionId: factionId,\n    };\n  },\n});\n\nvar mutationType = new GraphQLObjectType({\n  name: 'Mutation',\n  fields: () =\u003e ({\n    introduceShip: shipMutation,\n  }),\n});\n```\n\nThis 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.\n\nOur mutation type then creates the `introduceShip` field using the return value of `mutationWithClientMutationId`.\n\n## Contributing\n\nAfter cloning this repo, ensure dependencies are installed by running:\n\n```sh\nnpm install\n```\n\nThis library is written in ES6 and uses [Babel](https://babeljs.io/) for ES5 transpilation and [TypeScript](https://www.typescriptlang.org/) for type safety. Widely consumable JavaScript can be produced by running:\n\n```sh\nnpm run build\n```\n\nOnce `npm run build` has run, you may `import` or `require()` directly from node.\n\nAfter developing, the full test suite can be evaluated by running:\n\n```sh\nnpm test\n```\n\n## Opening a PR\n\nWe actively welcome pull requests. Learn how to [contribute](./.github/CONTRIBUTING.md).\n\nThis repository is managed by EasyCLA. Project participants must sign the free ([GraphQL Specification Membership agreement](https://preview-spec-membership.graphql.org) before making a contribution. You only need to do this one time, and it can be signed by [individual contributors](https://individual-spec-membership.graphql.org/) or their [employers](https://corporate-spec-membership.graphql.org/).\n\nTo 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.\n\nYou can find [detailed information here](https://github.com/graphql/graphql-wg/tree/main/membership). If you have issues, please email [operations@graphql.org](mailto:operations@graphql.org).\n\nIf 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](https://foundation.graphql.org/join).\n\n## Changelog\n\nChanges are tracked as [GitHub releases](https://github.com/graphql/graphql-js/releases).\n\n## License\n\ngraphql-relay-js is [MIT licensed](./LICENSE).\n","funding_links":[],"categories":["Libraries","TypeScript","Implementations","JavaScript","Uncategorized","Relay [🔝](#readme)"],"sub_categories":["JavaScript Libraries","JavaScript/TypeScript","Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql%2Fgraphql-relay-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphql%2Fgraphql-relay-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql%2Fgraphql-relay-js/lists"}