{"id":37833177,"url":"https://github.com/rgraphql/rgraphql","last_synced_at":"2026-01-19T12:11:10.660Z","repository":{"id":47702317,"uuid":"79478117","full_name":"rgraphql/rgraphql","owner":"rgraphql","description":"Live-updating and streaming GraphQL.","archived":false,"fork":false,"pushed_at":"2026-01-13T15:43:58.000Z","size":2723,"stargazers_count":222,"open_issues_count":2,"forks_count":5,"subscribers_count":8,"default_branch":"master","last_synced_at":"2026-01-14T15:11:16.254Z","etag":null,"topics":["go","graphql","realtime"],"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/rgraphql.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-01-19T17:38:57.000Z","updated_at":"2025-11-05T09:51:46.000Z","dependencies_parsed_at":"2023-10-13T02:46:09.440Z","dependency_job_id":"26fed9bb-d25f-489f-95a6-d028928308fb","html_url":"https://github.com/rgraphql/rgraphql","commit_stats":{"total_commits":420,"total_committers":6,"mean_commits":70.0,"dds":0.3595238095238096,"last_synced_commit":"fdab3f4a9f2bc08469c31a340ce29d0baabb98f0"},"previous_names":["rgraphql/magellan"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/rgraphql/rgraphql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgraphql%2Frgraphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgraphql%2Frgraphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgraphql%2Frgraphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgraphql%2Frgraphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rgraphql","download_url":"https://codeload.github.com/rgraphql/rgraphql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgraphql%2Frgraphql/sbom","scorecard":{"id":405905,"data":{"date":"2025-08-11","repo":{"name":"github.com/rgraphql/rgraphql","commit":"e9cb9df3a1e7dfc96a261e5ee5478e6666046bf1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.8,"checks":[{"name":"Maintained","score":5,"reason":"7 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/27 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:20","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:21","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/dependency-review.yml:11","Info: topLevel 'contents' permission set to 'read': .github/workflows/tests.yml:12","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":9,"reason":"dependency not pinned by hash detected -- score normalized to 9","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/rgraphql/rgraphql/tests.yml/master?enable=pin","Info:  11 out of  12 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (3) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-xffm-g5w8-qvg7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T21:15:19.798Z","repository_id":47702317,"created_at":"2025-08-18T21:15:19.798Z","updated_at":"2025-08-18T21:15:19.798Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28567869,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T08:53:44.001Z","status":"ssl_error","status_checked_at":"2026-01-19T08:52:40.245Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["go","graphql","realtime"],"created_at":"2026-01-16T15:50:56.008Z","updated_at":"2026-01-19T12:11:10.648Z","avatar_url":"https://github.com/rgraphql.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rGraphQL\n\n[![GoDoc Widget]][GoDoc]\n[![Go Report Card Widget]][Go Report Card]\n[![npm version][npm-version-image]][npm-url]\n\n\u003e Two-way streaming GraphQL over real-time transports like WebSockets.\n\n[GoDoc]: https://godoc.org/github.com/rgraphql/rgraphql\n[GoDoc Widget]: https://godoc.org/github.com/rgraphql/rgraphql?status.svg\n[Go Report Card Widget]: https://goreportcard.com/badge/github.com/rgraphql/rgraphql\n[Go Report Card]: https://goreportcard.com/report/github.com/rgraphql/rgraphql\n[npm-url]: https://npmjs.org/package/rgraphql\n[npm-version-image]: https://img.shields.io/npm/v/rgraphql.svg?style=flat\n\n## Introduction\n\n**rGraphQL** is a **Real-time Streaming GraphQL*** implementation for Go and TypeScript:\n\n - Uses any two-way communication channel with clients (e.x. **WebSockets**).\n - Analyzes Go code to automatically generate resolver code fitting a schema.\n - Streams real-time updates to both the request and response.\n - Efficiently packs data on the wire with Protobuf.\n - Simplifies writing resolver functions with a flexible and intuitive API surface.\n - Accepts standard GraphQL queries and produces real-time output.\n\nThe **rGraphQL** protocol allows your apps to efficiently request the exact set\nof data needed, encode it in an efficient format for transport, and stream live\ndiffs for real-time updates.\n\n## Getting Started\n\nrgraphql uses [graphql-go] to parse the schema.\n\nInstall the **rgraphql** command-line tool:\n\n```bash\ncd ~\nexport GO111MODULE=on\ngo get -v github.com/rgraphql/rgraphql/cmd/rgraphql@master\nrgraphql -h\n```\n\nWrite a simple schema file `schema.graphql`:\n\n```graphql\n# RootQuery is the root query object.\ntype RootQuery {\n  counter: Int\n}\n\nschema {\n    query: RootQuery\n}\n```\n\nWrite a simple resolver file `resolve.go`:\n\n```go\n// RootResolver resolves RootQuery\ntype RootResolver struct {}\n\n// GetCounter returns the counter value.\nfunc (r *RootResolver) GetCounter(ctx context.Context, outCh chan\u003c- int) {\n\tvar v int\n\tfor {\n\t\tselect {\n\t\tcase \u003c-ctx.Done():\n\t\t\treturn\n\t\tcase \u003c-time.After(time.Second):\n\t\t\tv++\n\t\t\toutCh \u003c- v\n\t\t}\n\t}\n}\n```\n\nTo analyze the example code in this repo:\n\n```bash\ncd ./example/simple\ngo run github.com/rgraphql/rgraphql/cmd/rgraphql \\\n   analyze --schema ./schema.graphql \\\n   --go-pkg github.com/rgraphql/rgraphql/example/simple \\\n   --go-query-type RootResolver \\\n   --go-output ./resolve/resolve.rgraphql.go\n```\n\nTo test the code out:\n\n```bash\ngo test -v github.com/rgraphql/rgraphql/example/simple/resolve\n```\n\nThe basic usage of the code is as follows:\n\n```go\n// parse schema\nmySchema, err := schema.Parse(schemaStr)\n// build one query tree per client\nqueryTree, err := sch.BuildQueryTree(errCh)\nerrCh := make(chan *proto.RGQLQueryError, 10)\n\n// the client generates a stream of commands like this:\nqtNode.ApplyTreeMutation(\u0026proto.RGQLQueryTreeMutation{\n    NodeMutation: []*proto.RGQLQueryTreeMutation_NodeMutation{\n        \u0026proto.RGQLQueryTreeMutation_NodeMutation{\n            NodeId:    0,\n            Operation: proto.RGQLQueryTreeMutation_SUBTREE_ADD_CHILD,\n            Node: \u0026proto.RGQLQueryTreeNode{\n                Id:        1,\n                FieldName: \"counter\",\n            },\n        },\n      },\n  })\n\n// results are encoded into a binary stream\nencoder := encoder.NewResultEncoder(50)\noutputCh := make(chan []byte)\ndoneCh := make(chan struct{})\ngo encoder.Run(ctx, outputCh)\n\n// start up the resolvers\n// rootRes is the type you provide for the root resolver.\nrootRes := \u0026simple.RootResolver{}\nresolverCtx := resolver.NewContext(ctx, qtNode, encoder)\n\n// ResolveRootQuery is a goroutine which calls your code \n// according to the ongoing queries, and formats the results\n// into the encoder.\ngo ResolveRootQuery(resolverCtx, rootRes)\n```\n\nA simple example and demo can be found under [./example/simple/resolve.go].\n\n[graphql-go]: https://github.com/graphql-go/graphql\n[rgraphql.Server]: https://godoc.org/github.com/rgraphql/rgraphql#Server\n[rgraphql.NewServer]: https://godoc.org/github.com/rgraphql/rgraphql#NewServer\n[rgraphql.FromSchema]: https://godoc.org/github.com/rgraphql/rgraphql#FromSchema\n[rgraphql.ParseSchema]: https://godoc.org/github.com/rgraphql/rgraphql#ParseSchema\n[./example/simple/resolve.go]: ./example/simple/resolve.go\n\n## Design\n\nThe rgraphql analyzer loads a GraphQL schema and a Go code package. It then\n\"fits\" the GraphQL schema to the Go code, generating more Go \"resolver\" code.\n\nAt runtime, the client specifies a stream of modifications to a single global\nGraphQL query. The client merges together query fragments from UI components,\nand informs the server of changes to this query as components are mounted and\nunmounted. The server starts and stops resolvers to produce the requested data,\nand delivers a binary-packed stream of encoded response data, using a highly\noptimized protocol. The client re-constructs the result object and provides it\nto the frontend code, similar to other GraphQL clients.\n\n## Implementation\n\nAny two-way communications channel can be used for server\u003c-\u003eclient communication.\n\nrgraphql builds results by executing resolver functions, which return data for a\nfield in the incoming query. Each type in the GraphQL schema must have a\nresolver function or field for each of its fields. The signature of these\nresolvers determines how rgraphql treats the returned data.\n\nFields can return streams of data over time, which creates a mechanism for\nlive-updating results. One possible implementation could consist of a WebSocket\nbetween a browser and server.\n\n## Resolvers\n\nThe analyzer tries to \"fit\" the schema to the functions you write. The order and\npresence of the arguments, the result types, the presence or lack of channels,\ncan be whatever is necessary for your application.\n\nAll resolvers can optionally take a `context.Context` as an argument. Without\nthis argument, the system will consider the resolver as being \"trivial.\" All\nstreaming / live resolvers MUST take a Context argument, as this is the only way\nfor the system to cancel a long-running operation.\n\nFunctions with a `Get` prefix - like `GetRegion() string` will also be\nrecognized by the system. This means that Protobuf types in Go will be handled\nautomatically.\n\nHere are some examples of resolvers you might write.\n\n### Basic Resolver Types\n\n```go\n// Return a string, non-nullable.\nfunc (*PersonResolver) Name() string {\n  return \"Jerry\"\n}\n\n// Return a string pointer, nullable.\n// Lack of context argument indicates \"trivial\" resolver.\n// Returning an error is optional for basic resolver types.\nfunc (*PersonResolver) Name() (*string, error) {\n\tresult := \"Jerry\"\n\treturn \u0026result, nil\n}\n\n// Arguments, inline type definition.\nfunc (*PersonResolver) Name(ctx context.Context, args *struct{ FirstOnly bool }) (*string, error) {\n  firstName := \"Jerry\"\n  lastName := \"Seinfeld\"\n  if args.FirstOnly {\n    return \u0026firstName, nil\n  }\n  fullName := fmt.Sprintf(\"%s %s\", firstName, lastName)\n  return \u0026fullName, nil\n}\n\ntype NameArgs struct {\n  FirstOnly bool\n}\n\n// Arguments, named type.\nfunc (*PersonResolver) Name(ctx context.Context, args *NameArgs) (*string, error) {\n  // same as last example.\n}\n```\n\n### Array Resolvers\n\nThere are several ways to return an array of items.\n\n```go\n// Return a slice of strings. Non-null: nil slice = 0 entries.\nfunc (r *SentenceResolver) Words() ([]string, error) {\n  return []string{\"test\", \"works\"}, nil\n}\n\n// Return a slice of strings. Nullable: nil pointer = null, nil slice = []\nfunc (r *SentenceResolver) Words() (*[]string, error) {\n  result := []string{\"test\", \"works\"}\n  return \u0026result, nil\n  // or: return nil, nil\n}\n\n// Return a slice of resolvers.\nfunc (r *PersonResolver) Friends() (*[]*PersonResolver, error) {\n  result := []*PersonResolver{\u0026PersonResolver{}, nil}\n  return \u0026result, nil\n}\n\n// Return a channel of strings.\n// Closing the channel marks it as done.\n// If the context is canceled, the system ignores anything put in the chan.\nfunc (r *PersonResolver) Friends() (\u003c-chan string, error) {\n  result := []*PersonResolver{\u0026PersonResolver{}, nil}\n  return \u0026result, nil\n}\n```\n\n### Streaming Basic Resolvers\n\nTo implement \"live\" resolvers, we take the following function structure:\n\n```go\n// Change a person's name over time.\n// Returning from the function marks the resolver as complete.\n// Streaming resovers must return a single error object.\n// Returning from the resolver function indicates the resolver is complete.\n// Closing the result channel is OK but the resolver should return soon after.\nfunc (r *PersonResolver) Name(ctx context.Context, args *struct{ FirstOnly bool }, resultChan chan\u003c- string) error {\n  done := ctx.Done()\n  i := 0\n  for {\n    i += 1\n    nextName := \"Tom \"+i\n    select {\n    case \u003c-done:\n      return nil\n    case resultChan\u003c-nextName:\n    }\n    select {\n    case \u003c-done:\n      return nil\n    case time.After(time.Duration(1)*time.Second):\n    }\n  }\n}\n```\n\nYou can also return a `[]\u003c-chan string`. The system will treat each array\nelement as a live-updating field. Closing a channel will delete an array\nelement. Sending a value over a channel will set the value of that array\nelement. You could also return a `\u003c-chan (\u003c-chan string)` to get the same effect\nwith an unknown number of array elements.\n\n\n## History\n\nAn older reflection-based implementation of this project is available in the\n\"legacy-reflect\" branch.\n\nSeveral other prototypes are available in the legacy- branches.\n\n## Developing\n\nIf using Go only, you don't need `yarn` or `Node.JS`.\n\nBifrost uses [Protobuf](https://protobuf.dev/) for message encoding.\n\nYou can re-generate the protobufs after changing any `.proto` file:\n\n```\n# stage the .proto file so yarn gen sees it\ngit add .\n# install deps\nyarn\n# generate the protobufs\nyarn gen\n```\n\nTo run the test suite:\n\n```\n# Go tests only\ngo test ./...\n# All tests\nyarn test\n# Lint\nyarn lint\n```\n\n### Developing on MacOS\n\nOn MacOS, some homebrew packages are required for `yarn gen`:\n\n```\nbrew install bash make coreutils gnu-sed findutils protobuf\nbrew link --overwrite protobuf\n```\n\nAdd to your .bashrc or .zshrc:\n\n```\nexport PATH=\"/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH\"\nexport PATH=\"/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH\"\nexport PATH=\"/opt/homebrew/opt/findutils/libexec/gnubin:$PATH\"\nexport PATH=\"/opt/homebrew/opt/make/libexec/gnubin:$PATH\"\n```\n\n## Support\n\nPlease open a [GitHub issue] with any questions / issues.\n\n[GitHub issue]: https://github.com/rgraphql/rgraphql/issues/new\n\n... or feel free to reach out on [Matrix Chat] or [Discord].\n\n[Discord]: https://discord.gg/KJutMESRsT\n[Matrix Chat]: https://matrix.to/#/#aperturerobotics:matrix.org\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgraphql%2Frgraphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frgraphql%2Frgraphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgraphql%2Frgraphql/lists"}