{"id":27248161,"url":"https://github.com/egt-ukraine/go2gql","last_synced_at":"2025-10-19T01:25:06.514Z","repository":{"id":57528628,"uuid":"142125003","full_name":"EGT-Ukraine/go2gql","owner":"EGT-Ukraine","description":"graphql-go schema generator by proto files","archived":false,"fork":false,"pushed_at":"2019-05-28T13:43:00.000Z","size":4381,"stargazers_count":33,"open_issues_count":0,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-10T23:07:49.731Z","etag":null,"topics":["api-gateway","codegenerator","graphql","graphql-go","proto","protobuf","protoc","schema","tool"],"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/EGT-Ukraine.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}},"created_at":"2018-07-24T07:58:31.000Z","updated_at":"2024-01-17T12:36:14.000Z","dependencies_parsed_at":"2022-09-03T19:11:52.274Z","dependency_job_id":null,"html_url":"https://github.com/EGT-Ukraine/go2gql","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EGT-Ukraine%2Fgo2gql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EGT-Ukraine%2Fgo2gql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EGT-Ukraine%2Fgo2gql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EGT-Ukraine%2Fgo2gql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EGT-Ukraine","download_url":"https://codeload.github.com/EGT-Ukraine/go2gql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248312155,"owners_count":21082638,"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":["api-gateway","codegenerator","graphql","graphql-go","proto","protobuf","protoc","schema","tool"],"created_at":"2025-04-10T23:07:54.768Z","updated_at":"2025-10-19T01:25:06.427Z","avatar_url":"https://github.com/EGT-Ukraine.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"go2gql\n==============\n\n[![Build Status](https://travis-ci.org/EGT-Ukraine/go2gql.svg?branch=master)](https://travis-ci.org/EGT-Ukraine/go2gql)\n[![Coverage Status](https://coveralls.io/repos/github/EGT-Ukraine/go2gql/badge.svg?branch=master)](https://coveralls.io/github/EGT-Ukraine/go2gql?branch=master)\n\nTool, which generates GraphQL Schema for [graphql-go](https://github.com/graphql-go/graphql) package based on external data sources\n\n## Installation\n```bash\n$ go get github.com/EGT-Ukraine/go2gql/cmd/go2gql\n```\n\n## Usage\n```\n$ ./go2gql -c \"\u003cconfig path\u003e\"\n```\n\n## Generation process\n### Plugins\nThe generation process is built around plugins. Plugin is a go type that implements interface\n\n```go\ntype Plugin interface {\n\tInit(*GenerateConfig, []Plugin) error\n\tPrepare() error\n\tName() string\n\tPrintInfo(info Infos)\n\tInfos() map[string]string\n\tGenerate() error\n}\n```\n\n1) reading config\n2) plugins initialization ( calling Init() method of each plugin )\n3) plugins preparation ( calling Prepare() method of each plugin )\n3) plugins generation ( calling Generate() method of each plugin )\n\n## Default plugins\nDefault plugins places in ./generator/plugins\n\n### `graphql` plugin\n`graphql` generates:\n - GraphQL Schema based on config and relying on data sent to him from other packages\n - GraphQL types and resolvers relying on data sent to him from other packages\n\n#### config example\nHere's a simple config example of how to generate such GraphQL schema\n```GraphQL\ntype Query {\n    fieldA FieldA\n}\ntype FieldA {\n    srvField SomeServiceObj\n}\ntype SomeServiceObj {\n    ... SomeService methods\n}\ntype Mutation {\n    ... SomeServiceMutations methods\n}\n```\n\n\n```yml\n...\n...\ngraphql_schemas:\n  - name: \"ExampleSchema\"                           # Schema name\n    output_path: \"./services_api/schema/auth.go\"    # Where to put schema code\n    output_package: \"schema\"                        # Package name\n    queries:\n      type: \"OBJECT\"\n      fields:\n        - field:       \"fieldA\"\n          type:        \"OBJECT\"                     # Field type (OBJECT|SERVICE)\n          object_name: \"FieldA\"\n          fields:\n            - field:        \"srvField\"\n              object_name:  \"SomeServiceObj\"\n              service:      \"SomeService\"           # Service name\n              type:         \"SERVICE\"\n              exclude_methods:\n                - \"excluded_method_1\"\n              filter_methods:\n                - \"excluded_method_1\"\n                - \"excluded_method_3\"\n\n    mutations:\n      # similary to queries\n      type: \"SERVICE\"\n      service: \"SomeServiceMutations\"\n...\n```\n\n\n### `proto2gql` plugin\n`proto2gql` plugin parses .proto files, defined in config and pass them to `graphql` plugin.\n\n#### Service names\nFor each service of each proto file, `proto2gql` adds two services to `graphql` plugins with names:\n - `ServiceName` or `ServiceAlias`\n - `ServiceName`Mutations or `ServiceAlias`Mutations\n\n#### Config example\n\n```yml\n...\n...\nproto2gql:\n    output_path: \"./proto_out/\"      # path, where to put generated code\n    paths:                           # path, where parser will search for imports\n        - \"./vendor\"\n        - \"$GOPATH/src\"\n    import_aliases:                  # imports aliases for all files\n        - google/protobuf/descriptor.proto: \"github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto\"\n        - google/protobuf/timestamp.proto:  \"github.com/golang/protobuf/ptypes/timestamp/timestamp.proto\"\n        - google/protobuf/empty.proto:      \"github.com/golang/protobuf/ptypes/empty/empty.proto\"\n    files:\n      # If you want to add some settings to imported .proto file, just add it here\n      - name: \"Name\"                  # name of .proto file\n        proto_path: \"./a.proto\"       # path to .proto file\n        output_path: \"./schema/name\"  # file-specific path, where to put generated code\n        proto_go_package: \"github.com/gogo/protobuf/types\" # Go package of .proto file grpc client (which was previously generated by `protoc`)\n        gql_messages_prefix: \"Msg\"    # prefix, which will be added to all generated GraphQL Messages(including maps)\n        gql_enums_prefix:    \"Enm\"    # prefix, which will be added to all generated GraphQL Enums\n        paths:                        # file specific path, where parser will search for imports\n          - \"./a_proto_deps/\"\n        imports_aiases:               # file specific imports aliases\n          - google/protobuf/timestamp.proto:  \"github.com/gogo/protobuf/protobuf/google/protobuf/timestamp.proto\"\n        services:                     # services settings\n          \"serviceName\":              # service name\n            service_name: \"someAlias\" # service name alias\n            methods:\n              \"methodName\":           # method name\n                alias: \"methodAlias\"\n                request_type: \"QUERY\" # method type in GraphQL Schema (QUERY|MUTATION)\n        messages:                     # messages settings\n          - \"Request$\":               # message name match regex\n              unwrap_field: true      # unpack input message field. Useful for google.protobuf.wrappers.\n              fields:\n                \"ip_address\":\n                  context_key: \"ip\"   # context key, where unmarshaller will get this field from\n          - \"Response$\":\n              unwrap_field: true      # In proto we can't use primitive or repeated type in method response.\n                                      # If unwrap_field = true unpack response gql object with 1 field.\n              error_field: \"Error\"    # name of payload error field\n      - ...\n      - ...\n\n\n...\n...\n```\n\n### `swagger2gql` plugin\n`proto2gql` plugin parses swagger files, defined in config and pass them to `graphql` plugin.\n\n#### Service names\nFor each tag of each swagger file, `proto2gql` adds two services to `graphql` plugins with names:\n - `pascalized(tag-name)` or `ServiceAlias`\n - `pascalized(tag-name)`Mutations or `ServiceAlias`Mutations\n\npascalized() here means, that it converts string to CamelCase format and removes all characters that is not valid in GraphQL Object name\n\n#### Config example\n```yml\n...\n...\nswagger2gql:\n    output_path: \"./swagger_out/\"           # Path, where to put generated code\n    objects:                                # GraphQL objects configs\n      - \"Response$\":                        # Object name\n          error_field: \"error\"              # name of payload error field\n      - \"InputParams$\":\n          fields:                           # Object fields config\n            ip:                             # field name\n              context_key: \"user_ip\"        # context key, where unmarshaller will get this field from\n    files:\n      - name: \"Swagger file number 1\"         # swagger file name\n        path: \"./service1/swagger.json\"       # path to swagger file\n        models_go_path: \"github.com/myproject/service1/client/models\" # path to generated using goswagger models\n        output_pkg: \"gql_service1\"            # output go package name\n        output_path: \"./service1/schema/\"     # file-specific path, where to put generated code\n        gql_objects_prefix: \"Srv1\"            # prefix, which will be added to all generated GraphQL Objects\n        tags:                                 # tags settings\n          \"some-swagger-tag\":                 # tag name\n            client_go_package: \"github.com/myproject/service1/client/some_swagger_tag/client\"   # go client package\n            service_name: \"SomeSwaggerTag\"    # service name alias\n            methods:                          # tag method settings\n              \"/somes\":                       # request path\n                get:                          # request method (get/post/put/options...)\n                  alias: \"get\"\n                  request_type: \"QUERY\"       # request type (QUERY|MUTATIONS)\n        params_config:                        # file specific object parameters settings\n         - param_name: \"user_id\"\n           context_key: \"user_id\"          \n        objects:                              # file specific objects settings\n         - \"Request$\":\n           fields:\n             \"user_id\":\n               context_key: \"user_id\"\n...\n...\n```\n\n\n### Simple plugin example\nHere's a simple plugin, that gets access to graphql plugin. Fetches information about services and their methods, and then, render them to .yml file\n\n```go\npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/EGT-Ukraine/go2gql/generator\"\n\t\"github.com/EGT-Ukraine/go2gql/generator/plugins/graphql\"\n)\n\nconst Name = \"gql_services_rules\"\n\ntype plugin struct {\n\tgqlPlugin *graphql.Plugin\n}\n\nfunc (p *plugin) Init(_ *generator.GenerateConfig, plugins []generator.Plugin) error {\n\tfor _, plugin := range plugins {\n\t\tif g, ok := plugin.(*graphql.Plugin); ok {\n\t\t\tp.gqlPlugin = g\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn errors.New(\"graphql plugin was not found\")\n}\n\nfunc (p plugin) Generate() error {\n\tfile, err := os.OpenFile(\"./services_access.yml\", os.O_TRUNC|os.O_WRONLY, 0666)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to open services_access.yml\")\n\t}\n\tdefer file.Close()\n\tfor _, typesFile := range p.gqlPlugin.Types() {\n\t\tfor _, service := range typesFile.Services {\n\t\t\tif len(service.QueryMethods) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfile.WriteString(service.Name + \":\\n\")\n\t\t\tfor _, method := range service.QueryMethods {\n\t\t\t\tfile.WriteString(\"   \" + method.Name + \":\\n\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\nfunc (plugin) Name() string                   { return Name }\nfunc (plugin) Prepare() error                 { return nil }\nfunc (plugin) PrintInfo(info generator.Infos) {}\nfunc (plugin) Infos() map[string]string       { return nil }\n\nfunc Plugin() generator.Plugin {\n\treturn new(plugin)\n}\nfunc main(){}\n```\n\n### Dataloader support\n\nConfig example:\n\n```yml\ndata_loaders:\n  output_path: \"./generated/schema/loaders/\"\n\nproto2gql:\n  output_path: \"./generated/schema\"\n  paths:\n    - \"vendor\"\n    - \"$GOPATH/src\"\n  imports_aliases:\n    - google/protobuf/empty.proto:      \"github.com/golang/protobuf/ptypes/empty/empty.proto\"\n  files:\n    - proto_path: \"./apis/reviews.proto\"\n      services:\n        ItemsReviewService:\n          methods:\n            List:\n              data_loaders:\n                ItemReviewsByIDs:\n                  request_field: \"filter.item_ids\"\n                  result_field: \"reviews\"\n                  match_field: \"item_id\"\n                  type: \"1-N\"                       # Relation type (1-N|1-1)\n                  wait_duration: 1h1m1s   ( WARNING!! this is only example, use some small duration)\n\n    - proto_path: \"./apis/category.proto\"\n      services:\n        CategoryService:\n          methods:\n            List:\n              data_loaders:\n                CategoriesByIDs:\n                  request_field: \"filter.ids\"\n                  result_field: \"categories\"\n                  match_field: \"id\"\n                  type: \"1-1\"\n                  wait_duration: 1s\n\n\n    - proto_path: \"./apis/user.proto\"\n      services:\n        UserService:\n          methods:\n            List:\n              data_loaders:\n                UsersByIDs:\n                  request_field: \"filter.ids\"\n                  result_field: \"users\"\n                  match_field: \"id\"\n                  type: \"1-1\"\n                  wait_duration: 1s\n    - proto_path: \"./apis/items.proto\"\n      services:\n        ItemsService:\n          methods:\n            List:\n              alias: \"list\"\n              request_type: \"QUERY\"\n      messages:\n        - \"Item$\":\n            data_loaders:\n              - field_name: \"category\"\n                key_field_name: \"category_id\"\n                data_loader_name: \"CategoriesByIDs\"\n              - field_name: \"comments\"\n                key_field_name: \"id\"\n                data_loader_name: \"CommentsLoader\"\n              - field_name: \"reviews\"\n                key_field_name: \"id\"\n                data_loader_name: \"ItemReviewsByIDs\"\n\nswagger2gql:\n  output_path: \"./generated/schema\"\n  files:\n    - name: \"Comments\"\n      path: \"apis/swagger.json\"\n      models_go_path: \"github.com/EGT-Ukraine/go2gql/tests/dataloader/generated/clients/models\"\n      tags:\n        \"comments-controller\":\n          service_name: \"CommentsService\"\n          client_go_package: \"github.com/EGT-Ukraine/go2gql/tests/dataloader/generated/clients/client/comments_controller\"\n          methods:\n            \"/items/comments/\":\n              post:\n                data_loader_provider:\n                  name: \"CommentsLoader\"\n                  wait_duration_ms: 5\n      objects:\n        - \"ItemComment$\":\n            data_loaders:\n              - field_name: \"user\"\n                key_field_name: \"user_id\"\n                data_loader_name: \"UserService\"\n\ngraphql_schemas:\n  - name: \"API\"\n    output_path: \"./generated/schema/api.go\"\n    output_package: \"schema\"\n    queries:\n      type: \"OBJECT\"\n      fields:\n        - field: \"items\"\n          object_name: \"Items\"\n          service: \"ItemsService\"\n          type: \"SERVICE\"\n\n\n```\n\nDefault wait duration 10ms.\n\nFull example can be found in [tests](https://github.com/EGT-Ukraine/go2gql/tree/master/tests/dataloader).  \n\n## Note to users migrating from older releases\n\n### Migrating from 1.x to 2.0\n\n### Swagger plugin\n\n`service_name` config field is removed.\nUse `queries_service_name` \u0026 `mutations_service_name` instead.\n\n### Proto plugin\n \n`alias` config field for services is removed.\n\nUse `queries_service_name` \u0026 `mutations_service_name` instead.\n\n## Migrating from 2.x to 3.0\n\n### Swagger plugin\n\n`queries_service_name` \u0026 `mutations_service_name` config fields is removed.\nUse `service_name` instead.\n\n### Proto plugin\n \n`queries_service_name` \u0026 `mutations_service_name` config fields is removed.\nUse `service_name` instead.\n\n\n### Migrating from 3.x to 4.0\ntracer.Tracer was replaced with opentracing.Tracer\n\nSchema initialization before:\n\n```\nimport \"github.com/EGT-Ukraine/go2gql/tracer\"\n\nvar tracer tracer.Tracer\n\nsch, err := schema.GetAPISchema(schemaApiClientsFactory.GetAPIClients(), schemaApiInterceptor, tracer)\n```\n\nnow:\n\n```\nimport opentracing_go \"github.com/opentracing/opentracing-go\"\n\nvar tracer opentracing_go.Tracer\n\nsch, err := schema.GetAPISchema(schemaApiClientsFactory.GetAPIClients(), schemaApiInterceptor, tracer)\n```\n\n### Migrating from 4.x to 5.0\n\n`github.com/saturn4er/graphql` dependency was replaced with original `github.com/graphql-go/graphql` package.\n\n### Migrating from 5.x to 6.0\n\nImplicit service \u0026 method registration in proto plugin disabled.\nFor now you must declare each proto service \u0026 method in config.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegt-ukraine%2Fgo2gql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegt-ukraine%2Fgo2gql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegt-ukraine%2Fgo2gql/lists"}