{"id":13514029,"url":"https://github.com/shurcooL/githubv4","last_synced_at":"2025-03-31T02:33:13.982Z","repository":{"id":21377008,"uuid":"92572310","full_name":"shurcooL/githubv4","owner":"shurcooL","description":"Package githubv4 is a client library for accessing GitHub GraphQL API v4 (https://docs.github.com/en/graphql).","archived":false,"fork":false,"pushed_at":"2024-07-27T22:26:12.000Z","size":414,"stargazers_count":1118,"open_issues_count":42,"forks_count":89,"subscribers_count":21,"default_branch":"main","last_synced_at":"2024-10-29T09:56:29.769Z","etag":null,"topics":["client","github","go","graphql"],"latest_commit_sha":null,"homepage":"","language":"Go","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/shurcooL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":"2017-05-27T05:05:31.000Z","updated_at":"2024-10-18T20:52:53.000Z","dependencies_parsed_at":"2024-11-18T10:00:25.337Z","dependency_job_id":"25062f95-6d56-4434-ac5d-c8ccaf85ddcc","html_url":"https://github.com/shurcooL/githubv4","commit_stats":{"total_commits":103,"total_committers":13,"mean_commits":7.923076923076923,"dds":0.5048543689320388,"last_synced_commit":"48295856cce734663ddbd790ff54800f784f3193"},"previous_names":["shurcool/githubql"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurcooL%2Fgithubv4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurcooL%2Fgithubv4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurcooL%2Fgithubv4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurcooL%2Fgithubv4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shurcooL","download_url":"https://codeload.github.com/shurcooL/githubv4/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246249233,"owners_count":20747168,"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":["client","github","go","graphql"],"created_at":"2024-08-01T05:00:43.852Z","updated_at":"2025-03-31T02:33:10.486Z","avatar_url":"https://github.com/shurcooL.png","language":"Go","readme":"githubv4\n========\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/shurcooL/githubv4.svg)](https://pkg.go.dev/github.com/shurcooL/githubv4)\n\nPackage `githubv4` is a client library for accessing GitHub GraphQL API v4 (https://docs.github.com/en/graphql).\n\nIf you're looking for a client library for GitHub REST API v3, the recommended package is [`github`](https://github.com/google/go-github#installation) (also known as `go-github`).\n\nFocus\n-----\n\n-\tFriendly, simple and powerful API.\n-\tCorrectness, high performance and efficiency.\n-\tSupport all of GitHub GraphQL API v4 via code generation from schema.\n\nInstallation\n------------\n\n```sh\ngo get github.com/shurcooL/githubv4\n```\n\nUsage\n-----\n\n### Authentication\n\nGitHub GraphQL API v4 [requires authentication](https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#authenticating-with-graphql). The `githubv4` package does not directly handle authentication. Instead, when creating a new client, you're expected to pass an `http.Client` that performs authentication. The easiest and recommended way to do this is to use the [`golang.org/x/oauth2`](https://golang.org/x/oauth2) package. You'll need an OAuth token from GitHub (for example, a [personal API token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)) with the right scopes. Then:\n\n```Go\nimport \"golang.org/x/oauth2\"\n\nfunc main() {\n\tsrc := oauth2.StaticTokenSource(\n\t\t\u0026oauth2.Token{AccessToken: os.Getenv(\"GITHUB_TOKEN\")},\n\t)\n\thttpClient := oauth2.NewClient(context.Background(), src)\n\n\tclient := githubv4.NewClient(httpClient)\n\t// Use client...\n}\n```\n\nIf you are using GitHub Enterprise, use [`githubv4.NewEnterpriseClient`](https://godoc.org/github.com/shurcooL/githubv4#NewEnterpriseClient):\n\n```Go\nclient := githubv4.NewEnterpriseClient(os.Getenv(\"GITHUB_ENDPOINT\"), httpClient)\n// Use client...\n```\n\n### Simple Query\n\nTo make a query, you need to define a Go type that corresponds to the GitHub GraphQL schema, and contains the fields you're interested in querying. You can look up the GitHub GraphQL schema at https://docs.github.com/en/graphql/reference/queries.\n\nFor example, to make the following GraphQL query:\n\n```GraphQL\nquery {\n\tviewer {\n\t\tlogin\n\t\tcreatedAt\n\t}\n}\n```\n\nYou can define this variable:\n\n```Go\nvar query struct {\n\tViewer struct {\n\t\tLogin     githubv4.String\n\t\tCreatedAt githubv4.DateTime\n\t}\n}\n```\n\nThen call `client.Query`, passing a pointer to it:\n\n```Go\nerr := client.Query(context.Background(), \u0026query, nil)\nif err != nil {\n\t// Handle error.\n}\nfmt.Println(\"    Login:\", query.Viewer.Login)\nfmt.Println(\"CreatedAt:\", query.Viewer.CreatedAt)\n\n// Output:\n//     Login: gopher\n// CreatedAt: 2017-05-26 21:17:14 +0000 UTC\n```\n\n### Scalar Types\n\nFor each scalar in the GitHub GraphQL schema listed at https://docs.github.com/en/graphql/reference/scalars, there is a corresponding Go type in package `githubv4`.\n\nYou can use these types when writing queries:\n\n```Go\nvar query struct {\n\tViewer struct {\n\t\tLogin          githubv4.String\n\t\tCreatedAt      githubv4.DateTime\n\t\tIsBountyHunter githubv4.Boolean\n\t\tBioHTML        githubv4.HTML\n\t\tWebsiteURL     githubv4.URI\n\t}\n}\n// Call client.Query() and use results in query...\n```\n\nHowever, depending on how you're planning to use the results of your query, it's often more convenient to use other Go types.\n\nThe `encoding/json` rules are used for converting individual JSON-encoded fields from a GraphQL response into Go values. See https://godoc.org/encoding/json#Unmarshal for details. The [`json.Unmarshaler`](https://godoc.org/encoding/json#Unmarshaler) interface is respected.\n\nThat means you can simplify the earlier query by using predeclared Go types:\n\n```Go\n// import \"time\"\n\nvar query struct {\n\tViewer struct {\n\t\tLogin          string    // E.g., \"gopher\".\n\t\tCreatedAt      time.Time // E.g., time.Date(2017, 5, 26, 21, 17, 14, 0, time.UTC).\n\t\tIsBountyHunter bool      // E.g., true.\n\t\tBioHTML        string    // E.g., `I am learning \u003ca href=\"https://graphql.org\"\u003eGraphQL\u003c/a\u003e!`.\n\t\tWebsiteURL     string    // E.g., \"https://golang.org\".\n\t}\n}\n// Call client.Query() and use results in query...\n```\n\nThe [`DateTime`](https://docs.github.com/en/graphql/reference/scalars#datetime) scalar is described as \"an ISO-8601 encoded UTC date string\". If you wanted to fetch in that form without parsing it into a `time.Time`, you can use the `string` type. For example, this would work:\n\n```Go\n// import \"html/template\"\n\ntype MyBoolean bool\n\nvar query struct {\n\tViewer struct {\n\t\tLogin          string        // E.g., \"gopher\".\n\t\tCreatedAt      string        // E.g., \"2017-05-26T21:17:14Z\".\n\t\tIsBountyHunter MyBoolean     // E.g., MyBoolean(true).\n\t\tBioHTML        template.HTML // E.g., template.HTML(`I am learning \u003ca href=\"https://graphql.org\"\u003eGraphQL\u003c/a\u003e!`).\n\t\tWebsiteURL     template.URL  // E.g., template.URL(\"https://golang.org\").\n\t}\n}\n// Call client.Query() and use results in query...\n```\n\n### Arguments and Variables\n\nOften, you'll want to specify arguments on some fields. You can use the `graphql` struct field tag for this.\n\nFor example, to make the following GraphQL query:\n\n```GraphQL\n{\n\trepository(owner: \"octocat\", name: \"Hello-World\") {\n\t\tdescription\n\t}\n}\n```\n\nYou can define this variable:\n\n```Go\nvar q struct {\n\tRepository struct {\n\t\tDescription string\n\t} `graphql:\"repository(owner: \\\"octocat\\\", name: \\\"Hello-World\\\")\"`\n}\n```\n\nThen call `client.Query`:\n\n```Go\nerr := client.Query(context.Background(), \u0026q, nil)\nif err != nil {\n\t// Handle error.\n}\nfmt.Println(q.Repository.Description)\n\n// Output:\n// My first repository on GitHub!\n```\n\nHowever, that'll only work if the arguments are constant and known in advance. Otherwise, you will need to make use of variables. Replace the constants in the struct field tag with variable names:\n\n```Go\n// fetchRepoDescription fetches description of repo with owner and name.\nfunc fetchRepoDescription(ctx context.Context, owner, name string) (string, error) {\n\tvar q struct {\n\t\tRepository struct {\n\t\t\tDescription string\n\t\t} `graphql:\"repository(owner: $owner, name: $name)\"`\n\t}\n```\n\nWhen sending variables to GraphQL, you need to use exact types that match GraphQL scalar types, otherwise the GraphQL server will return an error.\n\nSo, define a `variables` map with their values that are converted to GraphQL scalar types:\n\n```Go\n\tvariables := map[string]interface{}{\n\t\t\"owner\": githubv4.String(owner),\n\t\t\"name\":  githubv4.String(name),\n\t}\n```\n\nFinally, call `client.Query` providing `variables`:\n\n```Go\n\terr := client.Query(ctx, \u0026q, variables)\n\treturn q.Repository.Description, err\n}\n```\n\n### Inline Fragments\n\nSome GraphQL queries contain inline fragments. You can use the `graphql` struct field tag to express them.\n\nFor example, to make the following GraphQL query:\n\n```GraphQL\n{\n\trepositoryOwner(login: \"github\") {\n\t\tlogin\n\t\t... on Organization {\n\t\t\tdescription\n\t\t}\n\t\t... on User {\n\t\t\tbio\n\t\t}\n\t}\n}\n```\n\nYou can define this variable:\n\n```Go\nvar q struct {\n\tRepositoryOwner struct {\n\t\tLogin        string\n\t\tOrganization struct {\n\t\t\tDescription string\n\t\t} `graphql:\"... on Organization\"`\n\t\tUser struct {\n\t\t\tBio string\n\t\t} `graphql:\"... on User\"`\n\t} `graphql:\"repositoryOwner(login: \\\"github\\\")\"`\n}\n```\n\nAlternatively, you can define the struct types corresponding to inline fragments, and use them as embedded fields in your query:\n\n```Go\ntype (\n\tOrganizationFragment struct {\n\t\tDescription string\n\t}\n\tUserFragment struct {\n\t\tBio string\n\t}\n)\n\nvar q struct {\n\tRepositoryOwner struct {\n\t\tLogin                string\n\t\tOrganizationFragment `graphql:\"... on Organization\"`\n\t\tUserFragment         `graphql:\"... on User\"`\n\t} `graphql:\"repositoryOwner(login: \\\"github\\\")\"`\n}\n```\n\nThen call `client.Query`:\n\n```Go\nerr := client.Query(context.Background(), \u0026q, nil)\nif err != nil {\n\t// Handle error.\n}\nfmt.Println(q.RepositoryOwner.Login)\nfmt.Println(q.RepositoryOwner.Description)\nfmt.Println(q.RepositoryOwner.Bio)\n\n// Output:\n// github\n// How people build software.\n//\n```\n\n### Pagination\n\nImagine you wanted to get a complete list of comments in an issue, and not just the first 10 or so. To do that, you'll need to perform multiple queries and use pagination information. For example:\n\n```Go\ntype comment struct {\n\tBody   string\n\tAuthor struct {\n\t\tLogin     string\n\t\tAvatarURL string `graphql:\"avatarUrl(size: 72)\"`\n\t}\n\tViewerCanReact bool\n}\nvar q struct {\n\tRepository struct {\n\t\tIssue struct {\n\t\t\tComments struct {\n\t\t\t\tNodes    []comment\n\t\t\t\tPageInfo struct {\n\t\t\t\t\tEndCursor   githubv4.String\n\t\t\t\t\tHasNextPage bool\n\t\t\t\t}\n\t\t\t} `graphql:\"comments(first: 100, after: $commentsCursor)\"` // 100 per page.\n\t\t} `graphql:\"issue(number: $issueNumber)\"`\n\t} `graphql:\"repository(owner: $repositoryOwner, name: $repositoryName)\"`\n}\nvariables := map[string]interface{}{\n\t\"repositoryOwner\": githubv4.String(owner),\n\t\"repositoryName\":  githubv4.String(name),\n\t\"issueNumber\":     githubv4.Int(issue),\n\t\"commentsCursor\":  (*githubv4.String)(nil), // Null after argument to get first page.\n}\n\n// Get comments from all pages.\nvar allComments []comment\nfor {\n\terr := client.Query(ctx, \u0026q, variables)\n\tif err != nil {\n\t\treturn err\n\t}\n\tallComments = append(allComments, q.Repository.Issue.Comments.Nodes...)\n\tif !q.Repository.Issue.Comments.PageInfo.HasNextPage {\n\t\tbreak\n\t}\n\tvariables[\"commentsCursor\"] = githubv4.NewString(q.Repository.Issue.Comments.PageInfo.EndCursor)\n}\n```\n\nThere is more than one way to perform pagination. Consider additional fields inside [`PageInfo`](https://docs.github.com/en/graphql/reference/objects#pageinfo) object.\n\n### Mutations\n\nMutations often require information that you can only find out by performing a query first. Let's suppose you've already done that.\n\nFor example, to make the following GraphQL mutation:\n\n```GraphQL\nmutation($input: AddReactionInput!) {\n\taddReaction(input: $input) {\n\t\treaction {\n\t\t\tcontent\n\t\t}\n\t\tsubject {\n\t\t\tid\n\t\t}\n\t}\n}\nvariables {\n\t\"input\": {\n\t\t\"subjectId\": \"MDU6SXNzdWUyMTc5NTQ0OTc=\",\n\t\t\"content\": \"HOORAY\"\n\t}\n}\n```\n\nYou can define:\n\n```Go\nvar m struct {\n\tAddReaction struct {\n\t\tReaction struct {\n\t\t\tContent githubv4.ReactionContent\n\t\t}\n\t\tSubject struct {\n\t\t\tID githubv4.ID\n\t\t}\n\t} `graphql:\"addReaction(input: $input)\"`\n}\ninput := githubv4.AddReactionInput{\n\tSubjectID: targetIssue.ID, // ID of the target issue from a previous query.\n\tContent:   githubv4.ReactionContentHooray,\n}\n```\n\nThen call `client.Mutate`:\n\n```Go\nerr := client.Mutate(context.Background(), \u0026m, input, nil)\nif err != nil {\n\t// Handle error.\n}\nfmt.Printf(\"Added a %v reaction to subject with ID %#v!\\n\", m.AddReaction.Reaction.Content, m.AddReaction.Subject.ID)\n\n// Output:\n// Added a HOORAY reaction to subject with ID \"MDU6SXNzdWUyMTc5NTQ0OTc=\"!\n```\n\nDirectories\n-----------\n\n| Path                                                                                       | Synopsis                                                                            |\n|--------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|\n| [example/githubv4dev](https://pkg.go.dev/github.com/shurcooL/githubv4/example/githubv4dev) | githubv4dev is a test program currently being used for developing githubv4 package. |\n\nLicense\n-------\n\n-\t[MIT License](LICENSE)\n","funding_links":[],"categories":["Go","Third-party APIs","Utility","Repositories"],"sub_categories":["Utility/Miscellaneous","Fail injection"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FshurcooL%2Fgithubv4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FshurcooL%2Fgithubv4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FshurcooL%2Fgithubv4/lists"}