{"id":20831968,"url":"https://github.com/graphql-dotnet/relay","last_synced_at":"2025-05-08T00:42:01.130Z","repository":{"id":13462502,"uuid":"74501681","full_name":"graphql-dotnet/relay","owner":"graphql-dotnet","description":"A toolset for creating Relay.js compatible GraphQL servers in dotnet.","archived":false,"fork":false,"pushed_at":"2023-11-20T10:43:19.000Z","size":555,"stargazers_count":75,"open_issues_count":39,"forks_count":28,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-08T00:41:45.735Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","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-dotnet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2016-11-22T18:27:06.000Z","updated_at":"2024-08-18T18:50:16.000Z","dependencies_parsed_at":"2024-06-21T14:24:08.142Z","dependency_job_id":null,"html_url":"https://github.com/graphql-dotnet/relay","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-dotnet%2Frelay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-dotnet%2Frelay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-dotnet%2Frelay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-dotnet%2Frelay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/graphql-dotnet","download_url":"https://codeload.github.com/graphql-dotnet/relay/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252978673,"owners_count":21834911,"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":[],"created_at":"2024-11-18T00:09:40.971Z","updated_at":"2025-05-08T00:42:01.108Z","avatar_url":"https://github.com/graphql-dotnet.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GraphQL.Relay\n\n![License](https://img.shields.io/github/license/graphql-dotnet/relay)\n\n[![CodeQL analysis](https://github.com/graphql-dotnet/relay/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/graphql-dotnet/relay/actions/workflows/codeql-analysis.yml)\n\n[![codecov](https://codecov.io/gh/graphql-dotnet/relay/branch/master/graph/badge.svg?token=wTEXq34OBT)](https://codecov.io/gh/graphql-dotnet/relay)\n\n![Activity](https://img.shields.io/github/commit-activity/w/graphql-dotnet/relay)\n![Activity](https://img.shields.io/github/commit-activity/m/graphql-dotnet/relay)\n![Activity](https://img.shields.io/github/commit-activity/y/graphql-dotnet/relay)\n\n![Size](https://img.shields.io/github/repo-size/graphql-dotnet/relay)\n\nA collection of classes, tools, and utilities for creating Relay.js compatible GraphQL servers in dotnet.\n\nProvides the following packages:\n\n| Package       | Downloads                                                                                               | NuGet Latest                                                                                           |\n|---------------|---------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|\n| GraphQL.Relay | [![Nuget](https://img.shields.io/nuget/dt/GraphQL.Relay)](https://www.nuget.org/packages/GraphQL.Relay) | [![Nuget](https://img.shields.io/nuget/v/GraphQL.Relay)](https://www.nuget.org/packages/GraphQL.Relay) |\n\n## Usage\n\n### Setup\n\nAdd the Nuget package:\n\n```bash\n$\u003e dotnet add package GraphQL.Relay\n```\n\nEnsure your resolver for GraphQL can resolve:\n\n* `ConnectionType\u003c\u003e`\n* `EdgeType\u003c\u003e`\n* `NodeInterface`\n* `PageInfoType`\n\nIf you're using the resolver from MVC (`IServiceProvider`), that might look like this:\n\n```csharp\nservices.AddTransient(typeof(ConnectionType\u003c\u003e));\nservices.AddTransient(typeof(EdgeType\u003c\u003e));\nservices.AddTransient\u003cNodeInterface\u003e();\nservices.AddTransient\u003cPageInfoType\u003e();\n```\n\n### GraphTypes\n\nIncluded are a few GraphQL types and helpers for creating Connections, Mutations, and Nodes\n\n#### `QueryGraphType`\n\nA top level Schema query type, which defines the required `node` root query;\n\n```csharp\npublic class StarWarsQuery : QueryGraphType\n{\n  public StarWarsQuery() {\n    Field\u003cDroidType\u003e(\n      \"hero\",\n      resolve: context =\u003e new Droid { DroidId = \"1\", Name = \"R2-D2\" }\n    );\n  }\n}\n\npublic class StarWarsSchema : Schema\n{\n  public StarWarsSchema() {\n    Query = new StarWarsQuery();\n  }\n}\n```\n\n#### `NodeGraphType\u003cTSource, TOut\u003e`, `NodeGraphType\u003cTSource\u003e`, `NodeGraphType`\n\nNodeTypes, are `ObjectGraphType`s that implement the [`NodeInterface`](https://facebook.github.io/relay/docs/graphql-object-identification.html#content)\nand provide a `GetById` method, which allows Relay (via the `node()` Query) to refetch nodes when it needs to.\n\nNodes, also provide a convenient `Id()` method for defining global `id` fields, derived from the type `Name` and `Id`.\nIf your underlying type has a name conflict on the field `id`, the \"local\" Id will be prefixed with the type name,\ne.g. `Droid.Id -\u003e droidId`\n\n```csharp\npublic class Droid\n{\n  public string DroidId { get; set; }\n  public string Name { get; set; }\n}\n\npublic class DroidType : NodeGraphType\u003cDroid\u003e\n{\n  public DroidType()\n  {\n    Name = \"Droid\";\n\n    Id(d =\u003e d.DroidId); // adds an id Field as well as the `Droid` id field\n\n    Field\u003cStringGraphType\u003e(\"name\", \"The name of the droid.\");\n  }\n\n  public override Droid GetById(string droidId) {\n    return StarWarsData.GetDroidByIdAsync(droidId);\n  }\n}\n```\n\n#### Mutations\n\nRelay mutations specify a few constraints on top of the general GraphQL mutations. To accommodate this, there are\nmutation specific GraphTypes provided.\n\n#### `MutationGraphType`\n\nThe top level mutation type attached to the GraphQL Schema\n\n```csharp\npublic class StarWarsMutation : MutationGraphType\n{\n  public StarWarsMutation() {\n\n    Mutation\u003cCreateDroidInput, CreateDroidPayload\u003e(\"createDroid\");\n    Mutation\u003cDeleteDroidInput, DeleteDroidPayload\u003e(\"deleteDroid\");\n  }\n}\n\npublic class StarWarsSchema : Schema\n{\n  public StarWarsSchema() {\n    Query = new StarWarsQuery();\n    Mutation = new StarWarsMutation();\n  }\n}\n```\n\n#### `MutationInputGraphType`\n\nAn simple base class that defines a `clientMutationId` field. functionally identical to `InputObjectGraphType` otherwise\n\n#### `MutationPayloadGraphType\u003cTSource, TOut\u003e`, `MutationPayloadGraphType\u003cTSource\u003e`, `MutationPayloadGraphType`\n\nThe output ObjectGraphType containing the mutation payload, functionally similar to an `ObjectGraphType` with the\naddition of requiring a `MutateAndGetPayload()` method used to resolve the payload from the inputs.\n\n```csharp\npublic class CreateDroidPayload : MutationPayloadGraphType\u003cDroidPayload, Task\u003cDroidPayload\u003e\u003e\n{\n  public CreateDroidPayload()\n  {\n    Name = \"CreateDroidPayload\";\n\n    Field(\n      name: \"droid\",\n      type: typeof(Droid));\n  }\n\n  public override async Task\u003cDroidPayload\u003e MutateAndGetPayload(MutationInputs inputs)\n  {\n    string name = inputs.Get\u003cstring\u003e(\"name\");\n\n    Droid newDroid = await StarWarsData.CreateDroidAsync(name)\n\n    return new DroidPayload {\n      Droid = newDroid\n    };\n  }\n}\n```\n\n### Connections\n\nLuckily `GraphQL-dotnet` already provides helpful utilities for creating connection fields, on GraphTypes. In addition\nincluded here are a few more helpful methods for creating relay compatible Connections from IEnumerables.\n\n#### `Connection.ToConnection(IEnumerable items, ResolveConnectionContext context)`\n\nCreates a connection from an existing list of objects.\n\n```csharp\npublic class Droid\n{\n  public string DroidId { get; set; }\n  public string Name { get; set; }\n  public IEnumerable\u003cDroid\u003e Friends { get; set; }\n}\n\npublic class DroidType : ObjectGraphType\u003cDroid\u003e\n{\n  public DroidType()\n  {\n    Name = \"Droid\";\n\n    Field\u003cStringGraphType\u003e(\"name\", \"The name of the droid.\");\n\n    Connection\u003cDroidType\u003e()\n      .Name(\"friends\")\n      .Resolve(context =\u003e\n        ConnectionUtils.ToConnection(c.Source.Friends, context));\n  }\n}\n```\n\n#### `ConnectionUtils.ToConnection(IEnumerable items, ResolveConnectionContext context, int sliceStartIndex, int totalCount)`\n\nSimilar to the above, but creates a connection with the correct cursors, when you only have a slice of the entire set\nof items. Windowing the items based on the arguments.\n\n#### `ConnectionUtils.CursorToOffset(string cursor)`\n\nConvert a connection item cursor to the `int` index of the item in the set.\n\n#### `ConnectionUtils.OffsetToCursor(int offset)`\n\nConvert an index offset to a connection cursor.\n\n#### `ResolveConnectionContextExtensions.ToConnection\u003cTSource\u003e(this IResolveConnectionContext context, IQueryable\u003cTSource\u003e items)`\n\nCreates a connection from an IQueryable.\n\n```csharp\npublic class Droid\n{\n  public string DroidId { get; set; }\n  public string Name { get; set; }\n  public IQueryable\u003cDroid\u003e Friends { get; set; }\n}\n\npublic class DroidType : ObjectGraphType\u003cDroid\u003e\n{\n  public DroidType()\n  {\n    Name = \"Droid\";\n\n    Field\u003cStringGraphType\u003e(\"name\", \"The name of the droid.\");\n\n    Connection\u003cDroidType\u003e()\n      .Name(\"friends\")\n      .Resolve(context =\u003e context\n        .ToConnection(c.Source.Friends));\n  }\n}\n```\n\n## Contributors\n\nThis project exists thanks to all the people who contribute. \n\u003ca href=\"https://github.com/graphql-dotnet/relay/graphs/contributors\"\u003e\u003cimg src=\"https://contributors-img.web.app/image?repo=graphql-dotnet/relay\" /\u003e\u003c/a\u003e\n\nPRs are welcome! Looking for something to work on? The list of [open issues](https://github.com/graphql-dotnet/relay/issues)\nis a great place to start. You can help the project by simply responding to some of the [asked questions](https://github.com/graphql-dotnet/relay/issues?q=is%3Aissue+is%3Aopen+label%3Aquestion).\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-dotnet%2Frelay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphql-dotnet%2Frelay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-dotnet%2Frelay/lists"}