├── .bazelci └── presubmit.yml ├── .bazelrc ├── .bazelversion ├── .devcontainer └── devcontainer.json ├── .git-blame-ignore-revs ├── .github ├── Dockerfile ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug.md │ ├── documentation.md │ └── feature.md ├── PULL_REQUEST_TEMPLATE.md ├── README_GITHUB.md ├── dependabot.yml ├── stale.yml └── workflows │ ├── ci.yml │ ├── devcontainer.yml │ ├── release.yml │ └── renovate.yml ├── .gitignore ├── .goreleaser.yml ├── ADOPTERS.md ├── BUILD.bazel ├── CONTRIBUTING.md ├── LICENSE ├── MODULE.bazel ├── MODULE.bazel.lock ├── Makefile ├── README.md ├── WORKSPACE ├── bin └── .gitignore ├── buf.gen.yaml ├── buf.lock ├── buf.yaml ├── docs ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── _layouts │ └── default.html ├── assets │ └── images │ │ ├── architecture_introduction_diagram.svg │ │ └── gotemplates │ │ ├── postman.png │ │ └── swaggerui.png ├── docs │ ├── contributing │ │ ├── 2020_season_of_docs.md │ │ ├── getting_started.md │ │ └── index.md │ ├── development │ │ ├── grpc-gateway_v2_migration_guide.md │ │ ├── index.md │ │ └── installation_for_cygwin.md │ ├── faq.md │ ├── mapping │ │ ├── binary_file_uploads.md │ │ ├── custom_marshalers.md │ │ ├── customizing_openapi_output.md │ │ ├── customizing_your_gateway.md │ │ ├── examples.md │ │ ├── grpc_api_configuration.md │ │ ├── httpbody_messages.md │ │ ├── index.md │ │ ├── patch_feature.md │ │ └── using_ref_with_responses.md │ ├── operations │ │ ├── annotated_context.md │ │ ├── aws_gateway_integration.md │ │ ├── health_check.md │ │ ├── index.md │ │ ├── inject_router.md │ │ ├── logging.md │ │ └── tracing.md │ ├── overview │ │ ├── background.md │ │ ├── index.md │ │ └── usage.md │ ├── related_projects.md │ ├── tutorials │ │ ├── adding_annotations.md │ │ ├── creating_main.go.md │ │ ├── generating_stubs │ │ │ ├── index.md │ │ │ ├── using_buf.md │ │ │ └── using_protoc.md │ │ ├── index.md │ │ ├── introduction.md │ │ ├── learn_more.md │ │ └── simple_hello_world.md │ └── using_custom_query_parser.md ├── favicon.ico ├── index.md └── run.sh ├── examples └── internal │ ├── README.md │ ├── browser │ ├── .gitignore │ ├── README.md │ ├── a_bit_of_everything_service.spec.js │ ├── bin │ │ └── .gitignore │ ├── bower.json │ ├── echo_service.spec.js │ ├── gulpfile.js │ ├── index.html │ ├── package-lock.json │ └── package.json │ ├── clients │ ├── abe │ │ ├── .gitignore │ │ ├── .swagger-codegen-ignore │ │ ├── .swagger-codegen │ │ │ └── VERSION │ │ ├── BUILD.bazel │ │ ├── api │ │ │ └── swagger.yaml │ │ ├── api_a_bit_of_everything.go │ │ ├── api_camel_case_service_name.go │ │ ├── api_echo_rpc.go │ │ ├── api_snake_enum_service.go │ │ ├── client.go │ │ ├── configuration.go │ │ ├── enum_helper.go │ │ ├── model_a_bit_of_everything.go │ │ ├── model_a_bit_of_everything_1.go │ │ ├── model_a_bit_of_everything_2.go │ │ ├── model_a_bit_of_everything_3.go │ │ ├── model_a_bit_of_everything_4.go │ │ ├── model_a_bit_of_everything_5.go │ │ ├── model_a_bit_of_everything_6.go │ │ ├── model_a_bit_of_everything_7.go │ │ ├── model_a_bit_of_everything_8.go │ │ ├── model_a_bit_of_everything_nested.go │ │ ├── model_a_bit_of_everything_service_deep_path_echo_body.go │ │ ├── model_a_bit_of_everything_service_deep_path_echo_body_single_nested.go │ │ ├── model_a_bit_of_everything_service_post_with_empty_body_body.go │ │ ├── model_a_bit_of_everything_service_update_body.go │ │ ├── model_a_bit_of_everything_service_update_v2_body.go │ │ ├── model_book.go │ │ ├── model_examplepb_a_bit_of_everything.go │ │ ├── model_examplepb_a_bit_of_everything_repeated.go │ │ ├── model_examplepb_a_bit_of_everything_service_update_body.go │ │ ├── model_examplepb_bar.go │ │ ├── model_examplepb_body.go │ │ ├── model_examplepb_book.go │ │ ├── model_examplepb_check_status_response.go │ │ ├── model_examplepb_error_object.go │ │ ├── model_examplepb_error_response.go │ │ ├── model_examplepb_foo.go │ │ ├── model_examplepb_numeric_enum.go │ │ ├── model_examplepb_required_message_type_request.go │ │ ├── model_examplepb_snake_enum_response.go │ │ ├── model_examplepbsnake_case_0_enum.go │ │ ├── model_examplepbsnake_case_enum.go │ │ ├── model_message_path_enum_nested_path_enum.go │ │ ├── model_nested_deep_enum.go │ │ ├── model_oneofenum_example_enum.go │ │ ├── model_pathenum_path_enum.go │ │ ├── model_pathenumsnake_case_for_import.go │ │ ├── model_protobuf_any.go │ │ ├── model_protoexamplepb_foo.go │ │ ├── model_rpc_status.go │ │ ├── model_sub_string_message.go │ │ ├── model_the_book_to_update_.go │ │ ├── model_the_book_to_update__1.go │ │ ├── model_the_book_to_update_the_books_name_field_is_used_to_identify_the_book_to_be_updated_format_publisherspublisherbooksbook.go │ │ ├── model_update_v2_request_request_for_update_includes_the_message_and_the_update_mask.go │ │ ├── model_update_v2_request_request_for_update_includes_the_message_and_the_update_mask_1.go │ │ ├── model_v1exampledeep_pathsingle_nested_name_single_nested.go │ │ └── response.go │ ├── echo │ │ ├── .gitignore │ │ ├── .swagger-codegen-ignore │ │ ├── .swagger-codegen │ │ │ └── VERSION │ │ ├── BUILD.bazel │ │ ├── api │ │ │ └── swagger.yaml │ │ ├── api_echo_service.go │ │ ├── client.go │ │ ├── configuration.go │ │ ├── model_examplepb_dynamic_message.go │ │ ├── model_examplepb_dynamic_message_update.go │ │ ├── model_examplepb_embedded.go │ │ ├── model_examplepb_nested_message.go │ │ ├── model_examplepb_simple_message.go │ │ ├── model_protobuf_any.go │ │ ├── model_protobuf_null_value.go │ │ ├── model_rpc_status.go │ │ └── response.go │ ├── generateunboundmethods │ │ ├── .gitignore │ │ ├── .swagger-codegen-ignore │ │ ├── .swagger-codegen │ │ │ └── VERSION │ │ ├── BUILD.bazel │ │ ├── api │ │ │ └── swagger.yaml │ │ ├── api_generate_unbound_methods_echo_service.go │ │ ├── client.go │ │ ├── configuration.go │ │ ├── docs │ │ │ ├── ExamplepbGenerateUnboundMethodsSimpleMessage.md │ │ │ ├── GenerateUnboundMethodsEchoServiceApi.md │ │ │ ├── ProtobufAny.md │ │ │ └── RuntimeError.md │ │ ├── model_examplepb_generate_unbound_methods_simple_message.go │ │ ├── model_protobuf_any.go │ │ ├── model_rpc_status.go │ │ ├── model_runtime_error.go │ │ └── response.go │ ├── responsebody │ │ ├── .gitignore │ │ ├── .swagger-codegen-ignore │ │ ├── .swagger-codegen │ │ │ └── VERSION │ │ ├── BUILD.bazel │ │ ├── api │ │ │ └── swagger.yaml │ │ ├── api_response_body_service.go │ │ ├── client.go │ │ ├── configuration.go │ │ ├── docs │ │ │ ├── ExamplepbRepeatedResponseBodyOut.md │ │ │ ├── ExamplepbRepeatedResponseBodyOutResponse.md │ │ │ ├── ExamplepbRepeatedResponseStrings.md │ │ │ ├── ExamplepbResponseBodyMessage.md │ │ │ ├── ExamplepbResponseBodyMessageResponse.md │ │ │ ├── ExamplepbResponseBodyOut.md │ │ │ ├── ExamplepbResponseBodyOutResponse.md │ │ │ ├── ExamplepbResponseBodyReq.md │ │ │ ├── ExamplepbResponseBodyValue.md │ │ │ ├── ProtobufAny.md │ │ │ ├── ResponseBodyServiceApi.md │ │ │ ├── ResponseResponseType.md │ │ │ ├── RpcStatus.md │ │ │ ├── RuntimeError.md │ │ │ └── StreamResultOfExamplepbResponseBodyOut.md │ │ ├── model_examplepb_repeated_response_body_out.go │ │ ├── model_examplepb_repeated_response_body_out_response.go │ │ ├── model_examplepb_repeated_response_strings.go │ │ ├── model_examplepb_response_body_out.go │ │ ├── model_examplepb_response_body_out_response.go │ │ ├── model_examplepb_response_body_value.go │ │ ├── model_protobuf_any.go │ │ ├── model_response_response_type.go │ │ ├── model_rpc_status.go │ │ ├── model_stream_result_of_examplepb_response_body_out.go │ │ └── response.go │ ├── staticcheck.conf │ └── unannotatedecho │ │ ├── .gitignore │ │ ├── .swagger-codegen-ignore │ │ ├── .swagger-codegen │ │ └── VERSION │ │ ├── BUILD.bazel │ │ ├── api │ │ └── swagger.yaml │ │ ├── api_unannotated_echo_service.go │ │ ├── client.go │ │ ├── configuration.go │ │ ├── model_examplepb_numeric_enum.go │ │ ├── model_examplepb_unannotated_embedded.go │ │ ├── model_examplepb_unannotated_nested_message.go │ │ ├── model_examplepb_unannotated_simple_message.go │ │ ├── model_protobuf_any.go │ │ ├── model_rpc_status.go │ │ └── response.go │ ├── cmd │ ├── example-gateway-server │ │ ├── BUILD.bazel │ │ └── main.go │ └── example-grpc-server │ │ ├── BUILD.bazel │ │ └── main.go │ ├── gateway │ ├── BUILD.bazel │ ├── doc.go │ ├── gateway.go │ ├── handlers.go │ └── main.go │ ├── helloworld │ ├── BUILD.bazel │ ├── helloworld.pb.go │ ├── helloworld.pb.gw.go │ ├── helloworld.proto │ ├── helloworld.swagger.json │ └── helloworld_grpc.pb.go │ ├── integration │ ├── BUILD.bazel │ ├── client_test.go │ ├── integration_test.go │ └── main_test.go │ ├── proto │ ├── examplepb │ │ ├── BUILD.bazel │ │ ├── a_bit_of_everything.pb.go │ │ ├── a_bit_of_everything.pb.gw.go │ │ ├── a_bit_of_everything.proto │ │ ├── a_bit_of_everything.swagger.json │ │ ├── a_bit_of_everything_grpc.pb.go │ │ ├── echo_service.pb.go │ │ ├── echo_service.pb.gw.go │ │ ├── echo_service.proto │ │ ├── echo_service.swagger.json │ │ ├── echo_service_grpc.pb.go │ │ ├── enum_with_single_value.buf.gen.yaml │ │ ├── enum_with_single_value.pb.go │ │ ├── enum_with_single_value.pb.gw.go │ │ ├── enum_with_single_value.proto │ │ ├── enum_with_single_value.swagger.json │ │ ├── enum_with_single_value_grpc.pb.go │ │ ├── excess_body.pb.go │ │ ├── excess_body.pb.gw.go │ │ ├── excess_body.proto │ │ ├── excess_body.swagger.json │ │ ├── excess_body_grpc.pb.go │ │ ├── flow_combination.pb.go │ │ ├── flow_combination.pb.gw.go │ │ ├── flow_combination.proto │ │ ├── flow_combination.swagger.json │ │ ├── flow_combination_grpc.pb.go │ │ ├── generate_unbound_methods.buf.gen.yaml │ │ ├── generate_unbound_methods.pb.go │ │ ├── generate_unbound_methods.pb.gw.go │ │ ├── generate_unbound_methods.proto │ │ ├── generate_unbound_methods.swagger.json │ │ ├── generate_unbound_methods_grpc.pb.go │ │ ├── generated_input.proto │ │ ├── generated_input.swagger.json │ │ ├── ignore_comment.buf.gen.yaml │ │ ├── ignore_comment.pb.go │ │ ├── ignore_comment.pb.gw.go │ │ ├── ignore_comment.proto │ │ ├── ignore_comment.swagger.json │ │ ├── ignore_comment_grpc.pb.go │ │ ├── non_standard_names.pb.go │ │ ├── non_standard_names.pb.gw.go │ │ ├── non_standard_names.proto │ │ ├── non_standard_names.swagger.json │ │ ├── non_standard_names_grpc.pb.go │ │ ├── openapi_merge.buf.gen.yaml │ │ ├── openapi_merge.swagger.json │ │ ├── openapi_merge_a.pb.go │ │ ├── openapi_merge_a.pb.gw.go │ │ ├── openapi_merge_a.proto │ │ ├── openapi_merge_a.swagger.json │ │ ├── openapi_merge_a_grpc.pb.go │ │ ├── openapi_merge_b.pb.go │ │ ├── openapi_merge_b.pb.gw.go │ │ ├── openapi_merge_b.proto │ │ ├── openapi_merge_b.swagger.json │ │ ├── openapi_merge_b_grpc.pb.go │ │ ├── remove_internal_comment.buf.gen.yaml │ │ ├── remove_internal_comment.pb.go │ │ ├── remove_internal_comment.pb.gw.go │ │ ├── remove_internal_comment.proto │ │ ├── remove_internal_comment.swagger.json │ │ ├── remove_internal_comment_grpc.pb.go │ │ ├── response_body_service.pb.go │ │ ├── response_body_service.pb.gw.go │ │ ├── response_body_service.proto │ │ ├── response_body_service.swagger.json │ │ ├── response_body_service_grpc.pb.go │ │ ├── standalone_echo_service.buf.gen.yaml │ │ ├── standalone_echo_service.yaml │ │ ├── stream.pb.go │ │ ├── stream.pb.gw.go │ │ ├── stream.proto │ │ ├── stream.swagger.json │ │ ├── stream_grpc.pb.go │ │ ├── unannotated_echo_service.buf.gen.yaml │ │ ├── unannotated_echo_service.pb.go │ │ ├── unannotated_echo_service.pb.gw.go │ │ ├── unannotated_echo_service.proto │ │ ├── unannotated_echo_service.swagger.json │ │ ├── unannotated_echo_service.swagger.yaml │ │ ├── unannotated_echo_service.yaml │ │ ├── unannotated_echo_service_grpc.pb.go │ │ ├── use_go_template.buf.gen.yaml │ │ ├── use_go_template.pb.go │ │ ├── use_go_template.pb.gw.go │ │ ├── use_go_template.proto │ │ ├── use_go_template.swagger.json │ │ ├── use_go_template_grpc.pb.go │ │ ├── visibility_rule_echo_service.pb.go │ │ ├── visibility_rule_echo_service.pb.gw.go │ │ ├── visibility_rule_echo_service.proto │ │ ├── visibility_rule_echo_service_grpc.pb.go │ │ ├── visibility_rule_enums_as_ints_echo_service.buf.gen.yaml │ │ ├── visibility_rule_enums_as_ints_echo_service.swagger.json │ │ ├── visibility_rule_internal_echo_service.buf.gen.yaml │ │ ├── visibility_rule_internal_echo_service.swagger.json │ │ ├── visibility_rule_none_echo_service.buf.gen.yaml │ │ ├── visibility_rule_none_echo_service.swagger.json │ │ ├── visibility_rule_preview_and_internal_echo_service.buf.gen.yaml │ │ ├── visibility_rule_preview_and_internal_echo_service.swagger.json │ │ ├── visibility_rule_preview_echo_service.buf.gen.yaml │ │ ├── visibility_rule_preview_echo_service.swagger.json │ │ ├── wrappers.pb.go │ │ ├── wrappers.pb.gw.go │ │ ├── wrappers.proto │ │ ├── wrappers.swagger.json │ │ └── wrappers_grpc.pb.go │ ├── oneofenum │ │ ├── BUILD.bazel │ │ ├── oneof_enum.pb.go │ │ ├── oneof_enum.proto │ │ └── oneof_enum.swagger.json │ ├── pathenum │ │ ├── BUILD.bazel │ │ ├── path_enum.pb.go │ │ ├── path_enum.proto │ │ └── path_enum.swagger.json │ ├── standalone │ │ ├── BUILD.bazel │ │ └── unannotated_echo_service.pb.gw.go │ ├── sub │ │ ├── BUILD.bazel │ │ ├── message.pb.go │ │ ├── message.proto │ │ └── message.swagger.json │ └── sub2 │ │ ├── BUILD.bazel │ │ ├── message.pb.go │ │ ├── message.proto │ │ └── message.swagger.json │ └── server │ ├── BUILD.bazel │ ├── a_bit_of_everything.go │ ├── echo.go │ ├── excess_body.go │ ├── fieldmask_helper.go │ ├── flow_combination.go │ ├── main.go │ ├── non_standard_names.go │ ├── responsebody.go │ └── unannotatedecho.go ├── go.mod ├── go.sum ├── internal ├── casing │ ├── BUILD.bazel │ ├── LICENSE.md │ ├── README.md │ ├── camel.go │ └── camel_test.go ├── codegenerator │ ├── BUILD.bazel │ ├── doc.go │ ├── parse_req.go │ ├── parse_req_test.go │ └── supported_features.go ├── descriptor │ ├── BUILD.bazel │ ├── apiconfig │ │ ├── BUILD.bazel │ │ ├── apiconfig.pb.go │ │ ├── apiconfig.proto │ │ └── apiconfig.swagger.json │ ├── grpc_api_configuration.go │ ├── grpc_api_configuration_test.go │ ├── openapi_configuration.go │ ├── openapi_configuration_test.go │ ├── openapiconfig │ │ ├── BUILD.bazel │ │ ├── openapiconfig.pb.go │ │ ├── openapiconfig.proto │ │ └── openapiconfig.swagger.json │ ├── registry.go │ ├── registry_test.go │ ├── services.go │ ├── services_test.go │ ├── types.go │ └── types_test.go ├── generator │ ├── BUILD.bazel │ └── generator.go └── httprule │ ├── BUILD.bazel │ ├── compile.go │ ├── compile_test.go │ ├── fuzz.go │ ├── parse.go │ ├── parse_test.go │ ├── types.go │ └── types_test.go ├── non_module_deps.bzl ├── protoc-gen-grpc-gateway ├── BUILD.bazel ├── internal │ └── gengateway │ │ ├── BUILD.bazel │ │ ├── doc.go │ │ ├── generator.go │ │ ├── generator_test.go │ │ ├── template.go │ │ └── template_test.go └── main.go ├── protoc-gen-openapiv2 ├── BUILD.bazel ├── defs.bzl ├── internal │ └── genopenapi │ │ ├── BUILD.bazel │ │ ├── cycle_test.go │ │ ├── doc.go │ │ ├── format.go │ │ ├── format_test.go │ │ ├── generator.go │ │ ├── generator_test.go │ │ ├── helpers.go │ │ ├── helpers_go111_old.go │ │ ├── helpers_test.go │ │ ├── naming.go │ │ ├── naming_test.go │ │ ├── template.go │ │ ├── template_fuzz_test.go │ │ ├── template_test.go │ │ ├── testdata │ │ └── generator │ │ │ ├── path_item_object.prototext │ │ │ ├── path_item_object.swagger.yaml │ │ │ ├── x_go_type.prototext │ │ │ └── x_go_type.swagger.yaml │ │ ├── types.go │ │ └── types_test.go ├── main.go ├── main_test.go └── options │ ├── BUILD.bazel │ ├── annotations.pb.go │ ├── annotations.proto │ ├── annotations_protoopaque.pb.go │ ├── buf.gen.yaml │ ├── openapiv2.pb.go │ ├── openapiv2.proto │ └── openapiv2_protoopaque.pb.go ├── renovate.json ├── repositories.bzl ├── runtime ├── BUILD.bazel ├── context.go ├── context_test.go ├── convert.go ├── convert_test.go ├── doc.go ├── errors.go ├── errors_test.go ├── fieldmask.go ├── fieldmask_test.go ├── handler.go ├── handler_test.go ├── internal │ └── examplepb │ │ ├── BUILD.bazel │ │ ├── example.pb.go │ │ ├── example.proto │ │ ├── example.swagger.json │ │ ├── non_standard_names.pb.go │ │ ├── non_standard_names.proto │ │ ├── non_standard_names.swagger.json │ │ ├── non_standard_names_grpc.pb.go │ │ ├── proto2.pb.go │ │ ├── proto2.proto │ │ ├── proto2.swagger.json │ │ ├── proto3.pb.go │ │ ├── proto3.proto │ │ └── proto3.swagger.json ├── marshal_httpbodyproto.go ├── marshal_httpbodyproto_test.go ├── marshal_json.go ├── marshal_json_test.go ├── marshal_jsonpb.go ├── marshal_jsonpb_test.go ├── marshal_proto.go ├── marshal_proto_test.go ├── marshaler.go ├── marshaler_registry.go ├── marshaler_registry_test.go ├── mux.go ├── mux_internal_test.go ├── mux_test.go ├── pattern.go ├── pattern_test.go ├── proto2_convert.go ├── query.go ├── query_fuzz_test.go └── query_test.go └── utilities ├── BUILD.bazel ├── doc.go ├── pattern.go ├── readerfactory.go ├── string_array_flag.go ├── string_array_flag_test.go ├── trie.go └── trie_test.go /.bazelci/presubmit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platforms: 3 | ubuntu1804: 4 | build_flags: 5 | - "--build_tag_filters=-nolinux" 6 | build_targets: 7 | - "//..." 8 | test_flags: 9 | - "--features=race" 10 | - "--test_tag_filters=-nolinux" 11 | test_targets: 12 | - "//..." 13 | macos: 14 | build_flags: 15 | - "--build_tag_filters=-nomacos" 16 | build_targets: 17 | - "//..." 18 | test_flags: 19 | - "--features=race" 20 | - "--test_tag_filters=-nomacos" 21 | test_targets: 22 | - "//..." 23 | -------------------------------------------------------------------------------- /.bazelrc: -------------------------------------------------------------------------------- 1 | build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 2 | build --test_output=errors 3 | -------------------------------------------------------------------------------- /.bazelversion: -------------------------------------------------------------------------------- 1 | 8.2.1 2 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. 2 | { 3 | "name": "Go", 4 | "build": { 5 | "dockerfile": "../.github/Dockerfile" 6 | }, 7 | "features": { 8 | "ghcr.io/devcontainers/features/common-utils:2": {}, 9 | "ghcr.io/devcontainers/features/node:1": {}, 10 | "ghcr.io/devcontainers/features/go:1": {} 11 | }, 12 | "customizations": { 13 | "vscode": { 14 | "editor.formatOnSave": true, 15 | "go.toolsManagement.checkForUpdates": "local", 16 | "go.useLanguageServer": true, 17 | "go.gopath": "/go", 18 | "go.goroot": "/usr/local/go", 19 | "bazel.buildifierExecutable": "/go/bin/buildifier", 20 | "bazel.buildifierFixOnFormat": true, 21 | "bazel.enableCodeLens": true, 22 | "extensions": ["golang.Go", "bazelbuild.vscode-bazel"] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # .git-blame-ignore-revs 2 | # Formatted all protobuf files 3 | bc0110188a8ef8e232050c3d9b347198dc83536a 4 | -------------------------------------------------------------------------------- /.github/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.24.3 2 | 3 | RUN apt-get update && \ 4 | DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ 5 | wget \ 6 | unzip \ 7 | openjdk-17-jre \ 8 | bzip2 \ 9 | patch && \ 10 | apt-get clean -y && \ 11 | rm -rf /var/lib/apt/lists/* 12 | 13 | # Install swagger-codegen 14 | ENV SWAGGER_CODEGEN_VERSION=2.4.8 15 | RUN wget https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/${SWAGGER_CODEGEN_VERSION}/swagger-codegen-cli-${SWAGGER_CODEGEN_VERSION}.jar \ 16 | -O /usr/local/bin/swagger-codegen-cli.jar && \ 17 | echo '#!/bin/bash\njava -jar /usr/local/bin/swagger-codegen-cli.jar "$@"' > /usr/local/bin/swagger-codegen && \ 18 | chmod +x /usr/local/bin/swagger-codegen 19 | 20 | # Install Bazelisk as bazel to manage Bazel 21 | RUN go install github.com/bazelbuild/bazelisk@latest && \ 22 | mv $(which bazelisk) /usr/local/bin/bazel 23 | 24 | # Install buildifier for bazel formatting 25 | RUN go install github.com/bazelbuild/buildtools/buildifier@latest 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: Submit a bug report to help us improve 4 | --- 5 | 6 | ## 🐛 Bug Report 7 | 8 | (A clear and concise description of what the bug is.) 9 | 10 | ## To Reproduce 11 | 12 | (Write your steps here:) 13 | 14 | 1. Step 1... 15 | 1. Step 2... 16 | 1. Step 3... 17 | 18 | ## Expected behavior 19 | 20 | (Write what you thought would happen.) 21 | 22 | ## Actual Behavior 23 | 24 | (Write what happened. Add screenshots, if applicable.) 25 | 26 | ## Your Environment 27 | 28 | (Environment name, version and operating system.) 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 📚 Documentation 3 | about: Report an issue related to documentation 4 | --- 5 | 6 | ## 📚 Documentation 7 | 8 | (A clear and concise description of what the issue is.) 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature 3 | about: Submit a proposal/request for a new feature 4 | --- 5 | 6 | ## 🚀 Feature 7 | 8 | (A clear and concise description of what the feature is.) 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | #### References to other Issues or PRs 13 | 14 | 19 | 20 | #### Have you read the [Contributing Guidelines](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/CONTRIBUTING.md)? 21 | 22 | #### Brief description of what is fixed or changed 23 | 24 | #### Other comments 25 | -------------------------------------------------------------------------------- /.github/README_GITHUB.md: -------------------------------------------------------------------------------- 1 | ### What's up with the Dockerfile? 2 | 3 | The `Dockerfile` in this folder is used as the build environment when regenerating the files (see CONTRIBUTING.md). 4 | The canonical repository for this Dockerfile is `ghcr.io/grpc-ecosystem/grpc-gateway/build-env`. 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "bundler" # See documentation for possible values 9 | directory: "/docs" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | - package-ecosystem: "github-actions" 13 | directory: "/" 14 | schedule: 15 | interval: daily 16 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - help wanted 8 | - enhancement 9 | - security 10 | # Label to use when marking an issue as stale 11 | staleLabel: wontfix 12 | # Comment to post when marking an issue as stale. Set to `false` to disable 13 | markComment: > 14 | This issue has been automatically marked as stale because it has not had 15 | recent activity. It will be closed if no further activity occurs. Thank you 16 | for your contributions. 17 | # Comment to post when closing a stale issue. Set to `false` to disable 18 | closeComment: false 19 | -------------------------------------------------------------------------------- /.github/workflows/devcontainer.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths: 4 | - .devcontainer/devcontainer.json 5 | - .github/workflows/devcontainer.yml 6 | - .github/Dockerfile 7 | permissions: 8 | contents: read 9 | packages: write 10 | name: devcontainer 11 | jobs: 12 | rebuild: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 16 | - name: Login to GitHub Container Registry 17 | uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 18 | with: 19 | registry: ghcr.io 20 | username: ${{ github.repository_owner }} 21 | password: ${{ secrets.GITHUB_TOKEN }} 22 | - name: Rebuild dev container image 23 | uses: devcontainers/ci@8bf61b26e9c3a98f69cb6ce2f88d24ff59b785c6 # v0.3 24 | with: 25 | imageName: ghcr.io/grpc-ecosystem/grpc-gateway/build-env 26 | cacheFrom: ghcr.io/grpc-ecosystem/grpc-gateway/build-env 27 | push: filter 28 | refFilterForPush: refs/heads/main 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _output/ 2 | .idea 3 | 4 | # Bazel. 5 | bazel-bin 6 | bazel-genfiles 7 | bazel-grpc-gateway 8 | bazel-out 9 | bazel-testlogs 10 | 11 | # Go vendor directory 12 | vendor 13 | 14 | # Generated travis files 15 | .travis.yml 16 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | builds: 3 | - main: ./protoc-gen-grpc-gateway/main.go 4 | id: protoc-gen-grpc-gateway 5 | binary: protoc-gen-grpc-gateway 6 | env: 7 | - CGO_ENABLED=0 8 | goos: 9 | - linux 10 | - darwin 11 | - windows 12 | goarch: 13 | - amd64 14 | - arm64 15 | - main: ./protoc-gen-openapiv2/main.go 16 | id: protoc-gen-openapiv2 17 | binary: protoc-gen-openapiv2 18 | env: 19 | - CGO_ENABLED=0 20 | goos: 21 | - linux 22 | - darwin 23 | - windows 24 | goarch: 25 | - amd64 26 | - arm64 27 | archives: 28 | - name_template: '{{ .Binary }}-{{ .Tag }}-{{ .Os }}-{{if eq .Arch "amd64"}}x86_64{{else}}{{ .Arch }}{{end}}' 29 | format: binary 30 | source: 31 | enabled: true 32 | name_template: '{{ .ProjectName }}-{{ .Tag }}' 33 | dist: _output 34 | -------------------------------------------------------------------------------- /ADOPTERS.md: -------------------------------------------------------------------------------- 1 | # Adopters 2 | 3 | This is a list of organizations that have spoken publicly about their adoption or 4 | production users that have added themselves (in alphabetical order): 5 | 6 | - [Ad Hoc](http://adhocteam.us/) uses the gRPC-Gateway to serve millions of 7 | API requests per day. 8 | - [Chef](https://www.chef.io/) uses the gRPC-Gateway to provide the user-facing 9 | API of [Chef Automate](https://automate.chef.io/). Furthermore, the generated 10 | OpenAPI data serves as the basis for its [API documentation](https://automate.chef.io/docs/api/). 11 | The code is Open Source, [see `github.com/chef/automate`](https://github.com/chef/automate). 12 | - [Cho Tot](https://careers.chotot.com/about-us/) utilizes gRPC Gateway to seamlessly integrate HTTP and gRPC services, enabling efficient communication for both legacy and modern systems. 13 | - [Conduit](https://github.com/ConduitIO/conduit), a data streaming tool written in Go, 14 | uses the gRPC-Gateway since its very beginning to provide an HTTP API in addition to its gRPC API. 15 | This makes it easier to integrate with Conduit, and the generated OpenAPI data is used in the documentation. 16 | - [PITS Global Data Recovery Services](https://www.pitsdatarecovery.net/) uses the gRPC-Gateway to generate efficient reverse-proxy servers for internal needs. 17 | - [Scaleway](https://www.scaleway.com/en/) uses the gRPC-Gateway since 2018 to 18 | serve millions of API requests per day [1]. 19 | - [SpiceDB](https://github.com/authzed/spicedb) uses the gRPC-Gateway to handle 20 | requests for security-critical permissions checks in environments where gRPC 21 | is unavailable. 22 | 23 | If you have adopted the gRPC-Gateway and would like to be included in this list, 24 | feel free to submit a PR. 25 | 26 | [1]: [The odyssey of an HTTP request in Scaleway](https://www.youtube.com/watch?v=eLxD-zIUraE&feature=youtu.be&t=480). 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Gengo, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Gengo, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | /protoc-gen-go 2 | /protoc-gen-go-grpc 3 | /protoc-gen-grpc-gateway 4 | /protoc-gen-openapiv2 5 | -------------------------------------------------------------------------------- /buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - remote: buf.build/protocolbuffers/go:v1.35.1 4 | out: . 5 | opt: 6 | - paths=source_relative 7 | - remote: buf.build/grpc/go:v1.5.1 8 | out: . 9 | opt: 10 | - paths=source_relative 11 | - require_unimplemented_servers=false 12 | - local: protoc-gen-grpc-gateway 13 | out: . 14 | opt: 15 | - paths=source_relative 16 | - allow_repeated_fields_in_body=true 17 | - local: protoc-gen-openapiv2 18 | out: . 19 | opt: 20 | - allow_repeated_fields_in_body=true 21 | -------------------------------------------------------------------------------- /buf.lock: -------------------------------------------------------------------------------- 1 | # Generated by buf. DO NOT EDIT. 2 | version: v1 3 | deps: 4 | - remote: buf.build 5 | owner: googleapis 6 | repository: googleapis 7 | commit: 62f35d8aed1149c291d606d958a7ce32 8 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | .ruby-version 4 | .jekyll-cache 5 | .sass-cache 6 | _site 7 | -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "just-the-docs" 3 | group :jekyll_plugins do 4 | gem "github-pages" # GitHub Pages 5 | gem "jekyll-optional-front-matter" # GitHub Pages 6 | gem "jekyll-default-layout" # GitHub Pages 7 | gem "jekyll-titles-from-headings" # GitHub Pages 8 | gem "jekyll-readme-index" # GitHub Pages 9 | gem "jekyll-relative-links" # GitHub Pages 10 | gem 'jekyll-include-cache' # GitHub Pages 11 | end 12 | -------------------------------------------------------------------------------- /docs/assets/images/gotemplates/postman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/f120d8e68293faa7f21e8c63d3a41a8448b5097e/docs/assets/images/gotemplates/postman.png -------------------------------------------------------------------------------- /docs/assets/images/gotemplates/swaggerui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/f120d8e68293faa7f21e8c63d3a41a8448b5097e/docs/assets/images/gotemplates/swaggerui.png -------------------------------------------------------------------------------- /docs/docs/contributing/2020_season_of_docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Google Season of Docs 4 | nav_order: 1 5 | parent: Contributing 6 | --- 7 | 8 | # 2020 Season of Docs 9 | 10 |
11 | 12 |
13 | 14 | The gRPC-Gateway participated in the 2020 [Google Season of Docs](https://g.co/seasonofdocs). 15 | The project was completed by [@iamrajiv](https://github.com/iamrajiv). A summary of the project 16 | work can be found in the 17 | [project report](https://github.com/iamrajiv/GSoD-2020/blob/master/GSoD_2020_Project_Report.md). 18 | -------------------------------------------------------------------------------- /docs/docs/contributing/getting_started.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Getting started 4 | nav_order: 0 5 | parent: Contributing 6 | --- 7 | 8 | # How to contribute 9 | 10 | See [CONTRIBUTING.md](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/CONTRIBUTING.md). 11 | -------------------------------------------------------------------------------- /docs/docs/contributing/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Contributing 4 | nav_order: 5 5 | has_children: true 6 | --- 7 | -------------------------------------------------------------------------------- /docs/docs/development/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Development 4 | nav_order: 4 5 | has_children: true 6 | --- 7 | -------------------------------------------------------------------------------- /docs/docs/mapping/binary_file_uploads.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Binary file uploads 4 | nav_order: 2 5 | parent: Mapping 6 | --- 7 | 8 | # Binary file uploads 9 | 10 | If you need to do a binary file upload, e.g. via; 11 | 12 | ```sh 13 | curl -X POST -F "attachment=@/tmp/somefile.txt" http://localhost:9090/v1/files 14 | ``` 15 | 16 | then your request will contain the binary data directly and there is no way to model this using gRPC. 17 | 18 | What you can do instead is to add a custom route directly on the `mux` instance. 19 | 20 | ## Custom route on a mux instance 21 | 22 | Here we'll setup a handler (`handleBinaryFileUpload`) for `POST` requests: 23 | 24 | ```go 25 | // Create a mux instance 26 | mux := runtime.NewServeMux() 27 | 28 | // Attachment upload from http/s handled manually 29 | mux.HandlePath("POST", "/v1/files", handleBinaryFileUpload) 30 | ``` 31 | 32 | And then in your handler you can do something like: 33 | 34 | ```go 35 | func handleBinaryFileUpload(w http.ResponseWriter, r *http.Request, params map[string]string) { 36 | err := r.ParseForm() 37 | if err != nil { 38 | http.Error(w, fmt.Sprintf("failed to parse form: %s", err.Error()), http.StatusBadRequest) 39 | return 40 | } 41 | 42 | f, header, err := r.FormFile("attachment") 43 | if err != nil { 44 | http.Error(w, fmt.Sprintf("failed to get file 'attachment': %s", err.Error()), http.StatusBadRequest) 45 | return 46 | } 47 | defer f.Close() 48 | 49 | // 50 | // Now do something with the io.Reader in `f`, i.e. read it into a buffer or stream it to a gRPC client side stream. 51 | // Also `header` will contain the filename, size etc of the original file. 52 | // 53 | } 54 | ``` 55 | -------------------------------------------------------------------------------- /docs/docs/mapping/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Mapping 4 | nav_order: 2 5 | has_children: true 6 | --- 7 | -------------------------------------------------------------------------------- /docs/docs/mapping/using_ref_with_responses.md: -------------------------------------------------------------------------------- 1 | # Using arbitrary messages in response description 2 | 3 | Assuming a protobuf file of the structure 4 | 5 | ```protobuf 6 | syntax = "proto3"; 7 | 8 | package example.service.v1; 9 | 10 | import "protoc-gen-openapiv2/options/annotations.proto"; 11 | 12 | service GenericService { 13 | rpc GenericRPC(GenericRPCRequest) returns (GenericRPCResponse); 14 | } 15 | 16 | message GenericRPCRequest { 17 | string id = 1; 18 | } 19 | 20 | message GenericRPCResponse { 21 | string result = 1; 22 | } 23 | ``` 24 | 25 | If you want your OpenAPI document to include a custom response for all RPCs defined in this protobuf file, you can add the following: 26 | 27 | ```protobuf 28 | option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { 29 | responses: { 30 | key: "400" 31 | value: { 32 | description: "Returned when the request is malformed." 33 | schema: { 34 | json_schema: {ref: ".example.service.v1.GenericResponse"} // Must match the fully qualified name of the message 35 | } 36 | } 37 | } 38 | }; 39 | 40 | message GenericResponse { 41 | repeated string resources = 1; 42 | repeated string errors = 2; 43 | } 44 | ``` 45 | 46 | When generating, you will see the following response included in your OpenAPI document: 47 | 48 | ```json 49 | "400": { 50 | "description": "Returned when the request is malformed.", 51 | "schema": { 52 | "$ref": "#/definitions/v1GenericResponse" 53 | } 54 | }, 55 | ``` 56 | 57 | The annotation can also be specified per-rpc. -------------------------------------------------------------------------------- /docs/docs/operations/annotated_context.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Extracting the HTTP path pattern for a request 4 | nav_order: 4 5 | parent: Operations 6 | --- 7 | 8 | # Extracting the HTTP path pattern for a request 9 | 10 | It is often interesting to know what [HTTP path pattern](https://github.com/googleapis/googleapis/blob/869d32e2f0af2748ab530646053b23a2b80d9ca5/google/api/http.proto#L61-L87) was matched for a specific request, for example for metrics. This article explains how to extract the HTTP path pattern from the request context. 11 | 12 | ## Get HTTP Path pattern 13 | 1. Define the HTTP path in the proto annotation. For example: 14 | 15 | ```proto 16 | syntax = "proto3"; 17 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 18 | package grpc.gateway.examples.internal.proto.examplepb; 19 | 20 | import "google/api/annotations.proto"; 21 | 22 | service LoginService { 23 | rpc Login (LoginRequest) returns (LoginReply) { 24 | option (google.api.http) = { 25 | post: "/v1/example/login" 26 | body: "*" 27 | }; 28 | } 29 | } 30 | 31 | message LoginRequest {} 32 | 33 | message LoginReply {} 34 | ``` 35 | 36 | 2. At runtime, get the HTTP path pattern from the annotated context, for example using the `WithMetadata` function. 37 | You can pass data to your backend by adding them to the gRPC metadata or push them to a metrics server. 38 | 39 | ```go 40 | mux := runtime.NewServeMux( 41 | runtime.WithMetadata(func(ctx context.Context, r *http.Request) metadata.MD { 42 | md := make(map[string]string) 43 | if method, ok := runtime.RPCMethod(ctx); ok { 44 | md["method"] = method // /grpc.gateway.examples.internal.proto.examplepb.LoginService/Login 45 | } 46 | if pattern, ok := runtime.HTTPPathPattern(ctx); ok { 47 | md["pattern"] = pattern // /v1/example/login 48 | } 49 | return metadata.New(md) 50 | }), 51 | ) 52 | ``` -------------------------------------------------------------------------------- /docs/docs/operations/aws_gateway_integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: AWS gateway integration 4 | nav_order: 3 5 | parent: Operations 6 | --- 7 | 8 | # AWS gateway integration 9 | 10 | ## Import OpenAPI documentation into AWS API Gateway 11 | 12 | The AWS API Gateway service allows importing of an OpenAPI specification to create a REST API. The process is very straightforward and can be found [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html). 13 | 14 | Here are some tips to consider when importing the documentation: 15 | 16 | 1. Remove any circular dependencies (these aren't supported by the parser). 17 | 2. Remove security-related annotations (These annotations aren't well supported by the parser). 18 | 3. Max length of fields are reviewed by the parser but the errors aren't self-explanatory. Review the [specification](https://swagger.io/specification/v2/) to verify that the requirements are met. 19 | 4. API gateway errors aren't great, but you can use this [page](https://apidevtools.org/swagger-parser/online/) for structure validation. 20 | -------------------------------------------------------------------------------- /docs/docs/operations/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Operations 4 | nav_order: 3 5 | has_children: true 6 | --- 7 | -------------------------------------------------------------------------------- /docs/docs/operations/inject_router.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Adding custom routes to the mux 4 | nav_order: 0 5 | parent: Operations 6 | --- 7 | 8 | # Adding custom routes to the mux 9 | 10 | The gRPC-Gateway allows you to add custom routes to the serve mux, for example, if you want to support a use case that isn't supported by the gRPC-Gateway, like file uploads. 11 | 12 | ## Example 13 | 14 | ```go 15 | package main 16 | 17 | import ( 18 | "context" 19 | "net/http" 20 | 21 | pb "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/helloworld" 22 | "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 23 | ) 24 | 25 | func main() { 26 | ctx := context.TODO() 27 | mux := runtime.NewServeMux() 28 | // Register generated routes to mux 29 | err := pb.RegisterGreeterHandlerServer(ctx, mux, &GreeterServer{}) 30 | if err != nil { 31 | panic(err) 32 | } 33 | // Register custom route for GET /hello/{name} 34 | err = mux.HandlePath("GET", "/hello/{name}", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) { 35 | w.Write([]byte("hello " + pathParams["name"])) 36 | }) 37 | if err != nil { 38 | panic(err) 39 | } 40 | http.ListenAndServe(":8080", mux) 41 | } 42 | 43 | // GreeterServer is the server API for Greeter service. 44 | type GreeterServer struct { 45 | 46 | } 47 | 48 | // SayHello implement to say hello 49 | func (h *GreeterServer) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) { 50 | return &pb.HelloReply{ 51 | Message: "hello " + req.Name, 52 | }, nil 53 | } 54 | ``` 55 | -------------------------------------------------------------------------------- /docs/docs/overview/background.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Background 4 | nav_order: 0 5 | parent: Overview 6 | --- 7 | 8 | # Background 9 | 10 | gRPC is great -- it generates API clients and server stubs in many programming languages, it is fast, easy-to-use, bandwidth-efficient and its design is combat-proven by Google. However, you might still want to provide a traditional RESTful API as well. Reasons can range from maintaining backwards-compatibility, supporting languages or clients not well supported by gRPC to simply maintaining the aesthetics and tooling involved with a RESTful architecture. 11 | 12 | This project aims to provide that HTTP+JSON interface to your gRPC service. A small amount of configuration in your service to attach HTTP semantics is all that's needed to generate a reverse-proxy with this library. 13 | -------------------------------------------------------------------------------- /docs/docs/overview/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Overview 4 | nav_order: 1 5 | has_children: true 6 | --- 7 | -------------------------------------------------------------------------------- /docs/docs/overview/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: How do I use this? 4 | nav_order: 1 5 | parent: Overview 6 | --- 7 | 8 | # How do I use this? 9 | 10 | Follow the [instructions](https://github.com/grpc-ecosystem/grpc-gateway#usage) in the [README](https://github.com/grpc-ecosystem/grpc-gateway#readme). 11 | -------------------------------------------------------------------------------- /docs/docs/related_projects.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Related projects 4 | nav_order: 8 5 | --- 6 | 7 | # Related projects 8 | 9 | - [grpc-dynamic-gateway](https://github.com/konsumer/grpc-dynamic-gateway) 10 | 11 | A dynamically configured alternative to the grpc-gateway written in Node. 12 | 13 | - [rest2grpc](https://www.npmjs.com/package/rest2grpc) 14 | 15 | A statically configured alternative to the grpc-gateway written in Node. 16 | 17 | - The Envoy proxy [gRPC-JSON transcoder](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_json_transcoder_filter) 18 | 19 | An Envoy proxy filter that translates incoming JSON requests to gRPC and back. 20 | 21 | - Google Cloud Platform [HTTP/JSON gRPC transcoding](https://cloud.google.com/endpoints/docs/grpc/transcoding) 22 | 23 | A GCP product that behaves like the grpc-gateway. 24 | 25 | - gRPC gateway project generator [gen-grpc-gateway-api](https://github.com/akoserwal/gen-grpc-gateway-api) 26 | 27 | A shell script that can be used to generate a Go project that utilizes the gRPC-gateway and protobuf to expose a simple API. 28 | 29 | Tutorial guide: [Automate gRPC-Gateway project generation in Go with gen-grpc-gateway-api](https://akoserwal.medium.com/automate-grpc-gateway-project-generation-in-golang-with-gen-grpc-gateway-api-015759f1e51b) 30 | 31 | - [grpc-starter transcoding](https://danielliu1123.github.io/grpc-starter/docs/extensions/grpc-http-transcoding/) 32 | 33 | A Java implementation of grpc-gateway based on Spring Boot. 34 | -------------------------------------------------------------------------------- /docs/docs/tutorials/creating_main.go.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Creating main.go 4 | nav_order: 3 5 | parent: Tutorials 6 | --- 7 | 8 | # Creating main.go 9 | 10 | Before creating `main.go` file we are assuming that the user has created a `go.mod` with the name `github.com/myuser/myrepo`, if not please refer to [Creating go.mod file](introduction.md#creating-gomod-file). The import here is using the path to the generated files in `proto/helloworld` relative to the root of the repository. 11 | 12 | ```go 13 | package main 14 | 15 | import ( 16 | "context" 17 | "log" 18 | "net" 19 | 20 | "google.golang.org/grpc" 21 | 22 | helloworldpb "github.com/myuser/myrepo/proto/helloworld" 23 | ) 24 | 25 | type server struct{ 26 | helloworldpb.UnimplementedGreeterServer 27 | } 28 | 29 | func NewServer() *server { 30 | return &server{} 31 | } 32 | 33 | func (s *server) SayHello(ctx context.Context, in *helloworldpb.HelloRequest) (*helloworldpb.HelloReply, error) { 34 | return &helloworldpb.HelloReply{Message: in.Name + " world"}, nil 35 | } 36 | 37 | func main() { 38 | // Create a listener on TCP port 39 | lis, err := net.Listen("tcp", ":8080") 40 | if err != nil { 41 | log.Fatalln("Failed to listen:", err) 42 | } 43 | 44 | // Create a gRPC server object 45 | s := grpc.NewServer() 46 | // Attach the Greeter service to the server 47 | helloworldpb.RegisterGreeterServer(s, &server{}) 48 | // Serve gRPC Server 49 | log.Println("Serving gRPC on 0.0.0.0:8080") 50 | log.Fatal(s.Serve(lis)) 51 | } 52 | ``` 53 | 54 | ## Read More 55 | 56 | For more refer to gRPC docs [https://grpc.io/docs/languages/go/](https://grpc.io/docs/languages/go/). 57 | 58 | [Next](adding_annotations.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } 59 | -------------------------------------------------------------------------------- /docs/docs/tutorials/generating_stubs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Generating stubs 4 | parent: Tutorials 5 | nav_order: 2 6 | has_children: true 7 | --- 8 | 9 | For generating the stubs, we have two alternatives: `protoc` and `buf`. `protoc` is the more classic generation experience that is used widely in the industry, but it has a pretty steep learning curve. `buf` is a newer tool that is built with user experience and speed in mind. It also offers linting and breaking change detection, something `protoc` doesn't offer. We offer instructions for both here. 10 | -------------------------------------------------------------------------------- /docs/docs/tutorials/generating_stubs/using_protoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Generating stubs using protoc 4 | nav_order: 1 5 | parent: Generating stubs 6 | grand_parent: Tutorials 7 | --- 8 | 9 | # Generating stubs using protoc 10 | 11 | Here's an example of what a `protoc` command might look like to generate Go stubs, assuming that you're at the root of your repository and you have your proto files in a directory called `proto`: 12 | 13 | ```sh 14 | $ protoc -I ./proto \ 15 | --go_out ./proto --go_opt paths=source_relative \ 16 | --go-grpc_out ./proto --go-grpc_opt paths=source_relative \ 17 | ./proto/helloworld/hello_world.proto 18 | ``` 19 | 20 | We use the `go` and `go-grpc` plugins to generate Go types and gRPC service definitions. We're outputting the generated files relative to the `proto` folder, and we're using the `paths=source_relative` option, which means that the generated files will appear in the same directory as the source `.proto` file. 21 | 22 | This will have generated a `*.pb.go` and a `*_grpc.pb.go` file for `proto/helloworld/hello_world.proto`. 23 | 24 | [Next](../creating_main.go.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } 25 | -------------------------------------------------------------------------------- /docs/docs/tutorials/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Tutorials 4 | nav_order: 6 5 | has_children: true 6 | --- 7 | -------------------------------------------------------------------------------- /docs/docs/tutorials/learn_more.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Learn More 4 | nav_order: 5 5 | parent: Tutorials 6 | --- 7 | 8 | # Learn More 9 | 10 | ## How it works 11 | 12 | When the HTTP request arrives at the gRPC-Gateway, it parses the JSON data into a protobuf message. It then makes a normal Go gRPC client request using the parsed protobuf message. The Go gRPC client encodes the protobuf structure into the protobuf binary format and sends it to the gRPC server. The gRPC Server handles the request and returns the response in the protobuf binary format. The Go gRPC client parses it into a protobuf message and returns it to the gRPC-Gateway, which encodes the protobuf message to JSON and returns it to the original client. 13 | 14 | ## google.api.http 15 | 16 | Read more about `google.api.http` in [the source file documentation](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto). 17 | 18 | ## HTTP and gRPC Transcoding 19 | 20 | Read more about HTTP and gRPC Transcoding on [AIP 127](https://google.aip.dev/127). 21 | -------------------------------------------------------------------------------- /docs/docs/tutorials/simple_hello_world.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Creating a simple hello world with gRPC 4 | nav_order: 1 5 | parent: Tutorials 6 | --- 7 | 8 | # Creating a simple hello world with gRPC 9 | 10 | To understand the gRPC-Gateway we are going to first make a hello world gRPC service. 11 | 12 | ## Defining your gRPC service using protocol buffers 13 | 14 | Before we create a gRPC service, we should create a proto file to define what we need, here we create a file named `hello_world.proto` in the directory `proto/helloworld/hello_world.proto`. 15 | 16 | The gRPC service is defined using [Google Protocol Buffers](https://developers.google.com/protocol-buffers). To learn more about how to define a service in a `.proto` file see their [Basics tutorial](https://grpc.io/docs/languages/go/basics/). For now, all you need to know is that both the server and the client stub have a `SayHello()` RPC method that takes a `HelloRequest` parameter from the client and returns a `HelloReply` from the server, and that the method is defined like this: 17 | 18 | ```protobuf 19 | syntax = "proto3"; 20 | 21 | package helloworld; 22 | 23 | // The greeting service definition 24 | service Greeter { 25 | // Sends a greeting 26 | rpc SayHello (HelloRequest) returns (HelloReply) {} 27 | } 28 | 29 | // The request message containing the user's name 30 | message HelloRequest { 31 | string name = 1; 32 | } 33 | 34 | // The response message containing the greetings 35 | message HelloReply { 36 | string message = 1; 37 | } 38 | ``` 39 | 40 | [Next](generating_stubs/index.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } 41 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/f120d8e68293faa7f21e8c63d3a41a8448b5097e/docs/favicon.ico -------------------------------------------------------------------------------- /docs/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -e 4 | 5 | JEKYLL_VERSION=4 6 | BUNDLE_DIR="/tmp/grpc-gateway-bundle" 7 | 8 | if [ ! -d "${BUNDLE_DIR}" ]; then 9 | mkdir "${BUNDLE_DIR}" 10 | 11 | # Run this to update the Gemsfile.lock 12 | docker run --rm \ 13 | --volume="${PWD}:/srv/jekyll" \ 14 | -e "JEKYLL_UID=$(id -u)" \ 15 | -e "JEKYLL_GID=$(id -g)" \ 16 | --volume="/tmp/grpc-gateway-bundle:/usr/local/bundle" \ 17 | -it "jekyll/builder:${JEKYLL_VERSION}" \ 18 | bundle update 19 | fi 20 | 21 | if [[ ${JEKYLL_GITHUB_TOKEN} == "" ]]; then 22 | echo "Please set \$JEKYLL_GITHUB_TOKEN before running" 23 | exit 1 24 | fi 25 | 26 | docker run --rm \ 27 | --volume="${PWD}:/srv/jekyll" \ 28 | -p 35729:35729 -p 4000:4000 \ 29 | -e "JEKYLL_UID=$(id -u)" \ 30 | -e "JEKYLL_GID=$(id -g)" \ 31 | -e "JEKYLL_GITHUB_TOKEN=${JEKYLL_GITHUB_TOKEN}" \ 32 | --volume="/tmp/grpc-gateway-bundle:/usr/local/bundle" \ 33 | -it "jekyll/builder:${JEKYLL_VERSION}" \ 34 | jekyll serve 35 | -------------------------------------------------------------------------------- /examples/internal/README.md: -------------------------------------------------------------------------------- 1 | # One way to run the example 2 | 3 | ```bash 4 | # Handle dependencies 5 | $ dep init 6 | ``` 7 | 8 | Follow the guides from this [README.md](./browser/README.md) to run the server and gateway. 9 | ```bash 10 | # Make sure you are in the correct directory: 11 | # $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/v2/examples 12 | $ cd examples/internal/browser 13 | $ pwd 14 | 15 | # Install gulp 16 | $ npm install -g gulp-cli 17 | $ npm install 18 | $ gulp 19 | 20 | # Run 21 | $ gulp bower 22 | $ gulp backends 23 | ``` 24 | 25 | Then you can use curl or a browser to test: 26 | 27 | ```bash 28 | # List all apis 29 | $ curl http://localhost:8080/openapiv2/echo_service.swagger.json 30 | 31 | # Visit the apis 32 | $ curl -XPOST http://localhost:8080/v1/example/echo/foo 33 | {"id":"foo"} 34 | 35 | $ curl http://localhost:8080/v1/example/echo/foo/123 36 | {"id":"foo","num":"123"} 37 | 38 | ``` 39 | 40 | So you have visited the apis by HTTP successfully. You can also try other apis. 41 | -------------------------------------------------------------------------------- /examples/internal/browser/.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components 2 | /node_modules 3 | -------------------------------------------------------------------------------- /examples/internal/browser/README.md: -------------------------------------------------------------------------------- 1 | # Browser example 2 | 3 | This directory contains an example use of gRPC-Gateway with web browsers. 4 | The following commands automatically runs integration tests with phantomjs. 5 | 6 | ```shell-session 7 | $ npm install -g gulp-cli 8 | $ npm install 9 | $ gulp 10 | ``` 11 | 12 | ## Other examples 13 | 14 | ### Very simple example 15 | 16 | Run 17 | 18 | ```shell-session 19 | $ gulp bower 20 | $ gulp backends 21 | ``` 22 | 23 | then, open `index.html`. 24 | 25 | ### Integration test with your browser 26 | 27 | Run 28 | 29 | ```shell-session 30 | $ gulp serve 31 | ``` 32 | 33 | then, open `http://localhost:8000` with your browser. 34 | -------------------------------------------------------------------------------- /examples/internal/browser/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | !/.gitignore 3 | -------------------------------------------------------------------------------- /examples/internal/browser/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-gateway-example-browser", 3 | "description": "Example use of gRPC-Gateway from browser", 4 | "main": "index.js", 5 | "authors": [ 6 | "Yuki Yugui Sonoda " 7 | ], 8 | "license": "SEE LICENSE IN LICENSE file", 9 | "homepage": "https://github.com/grpc-ecosystem/grpc-gateway", 10 | "private": true, 11 | "dependencies": { 12 | "swagger-js": "~> 2.1" 13 | }, 14 | "ignore": [ 15 | "**/.*", 16 | "node_modules", 17 | "bower_components", 18 | "test", 19 | "tests" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /examples/internal/browser/echo_service.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var SwaggerClient = require('swagger-client'); 4 | 5 | describe('EchoService', function () { 6 | var client; 7 | 8 | beforeEach(function (done) { 9 | new SwaggerClient({ 10 | url: "http://localhost:8080/openapiv2/echo_service.swagger.json", 11 | usePromise: true, 12 | }).then(function (c) { 13 | client = c; 14 | done(); 15 | }); 16 | }); 17 | 18 | describe('Echo', function () { 19 | it('should echo the request back', function (done) { 20 | var expected = { 21 | id: "foo", 22 | num: "0", 23 | status: null 24 | }; 25 | client.EchoService.EchoService_Echo( 26 | expected, 27 | { responseContentType: "application/json" } 28 | ).then(function (resp) { 29 | expect(resp.obj).toEqual(expected); 30 | }).catch(function (err) { 31 | done.fail(err); 32 | }).then(done); 33 | }); 34 | }); 35 | 36 | describe('EchoBody', function () { 37 | it('should echo the request back', function (done) { 38 | var expected = { 39 | id: "foo", 40 | num: "0", 41 | status: null 42 | }; 43 | client.EchoService.EchoService_EchoBody( 44 | { body: expected }, 45 | { responseContentType: "application/json" } 46 | ).then(function (resp) { 47 | expect(resp.obj).toEqual(expected); 48 | }).catch(function (err) { 49 | done.fail(err); 50 | }).then(done); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /examples/internal/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/internal/browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-gateway-example", 3 | "version": "1.0.0", 4 | "description": "Example use of gRPC-Gateway from browser", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "SEE LICENSE", 10 | "devDependencies": { 11 | "bower": "^1.7.9", 12 | "bower-config": "^0.6.2", 13 | "bower-logger": "^0.2.2", 14 | "configstore": "^4.0.0", 15 | "gulp": "^3.9.1", 16 | "gulp-bower": "0.0.13", 17 | "gulp-exit": "0.0.2", 18 | "gulp-jasmine-browser": "^1.3.2", 19 | "gulp-shell": "^0.5.2", 20 | "jasmine": "^2.4.1", 21 | "mout": "^1.2.4", 22 | "phantomjs": "^2.1.7", 23 | "swagger-client": "^2.1.28", 24 | "webpack-stream": "^3.2.0" 25 | }, 26 | "dependencies": { 27 | "gulp-cli": "^2.3.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/.gitignore: -------------------------------------------------------------------------------- 1 | /docs 2 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | 2.4.8 -------------------------------------------------------------------------------- /examples/internal/clients/abe/enum_helper.go: -------------------------------------------------------------------------------- 1 | package abe 2 | 3 | import ( 4 | pbexamplepb "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb" 5 | pbpathenum "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/pathenum" 6 | "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 7 | ) 8 | 9 | // String returns a string representation of "NumericEnum" 10 | func (e ExamplepbNumericEnum) String() string { 11 | return pbexamplepb.NumericEnum_ONE.String() 12 | } 13 | 14 | // UnmarshalJSON does a no-op unmarshal to ExamplepbNumericEnum. 15 | // It just validates that the input is sane. 16 | func (e ExamplepbNumericEnum) UnmarshalJSON(b []byte) error { 17 | return unmarshalJSONEnum(b, pbexamplepb.NumericEnum_value) 18 | } 19 | 20 | // String returns a string representation of "MessagePathEnum" 21 | func (e MessagePathEnumNestedPathEnum) String() string { 22 | return pbpathenum.MessagePathEnum_JKL.String() 23 | } 24 | 25 | // UnmarshalJSON does a no-op unmarshal to MessagePathEnumNestedPathEnum. 26 | // It just validates that the input is sane. 27 | func (e MessagePathEnumNestedPathEnum) UnmarshalJSON(b []byte) error { 28 | return unmarshalJSONEnum(b, pbpathenum.MessagePathEnum_NestedPathEnum_value) 29 | } 30 | 31 | // String returns a string representation of "PathEnum" 32 | func (e PathenumPathEnum) String() string { 33 | return pbpathenum.PathEnum_DEF.String() 34 | } 35 | 36 | // UnmarshalJSON does a no-op unmarshal to PathenumPathEnum. 37 | // It just validates that the input is sane. 38 | func (e PathenumPathEnum) UnmarshalJSON(b []byte) error { 39 | return unmarshalJSONEnum(b, pbpathenum.PathEnum_value) 40 | } 41 | 42 | func unmarshalJSONEnum(b []byte, enumValMap map[string]int32) error { 43 | val := string(b[1 : len(b)-1]) 44 | _, err := runtime.Enum(val, enumValMap) 45 | return err 46 | } 47 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_a_bit_of_everything_nested.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | // Nested is nested type. 14 | type ABitOfEverythingNested struct { 15 | // name is nested field. 16 | Name string `json:"name,omitempty"` 17 | Amount int64 `json:"amount,omitempty"` 18 | // DeepEnum description. 19 | Ok *NestedDeepEnum `json:"ok,omitempty"` 20 | } 21 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_a_bit_of_everything_service_deep_path_echo_body_single_nested.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | // Nested is nested type. 14 | type ABitOfEverythingServiceDeepPathEchoBodySingleNested struct { 15 | Amount int64 `json:"amount,omitempty"` 16 | // DeepEnum description. 17 | Ok *NestedDeepEnum `json:"ok,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_a_bit_of_everything_service_post_with_empty_body_body.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ABitOfEverythingServicePostWithEmptyBodyBody struct { 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_a_bit_of_everything_service_update_v2_body.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ABitOfEverythingServiceUpdateV2Body struct { 14 | Abe *ABitOfEverything2 `json:"abe,omitempty"` 15 | // The paths to update. 16 | UpdateMask string `json:"updateMask,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_book.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | import ( 14 | "time" 15 | ) 16 | 17 | // An example resource type from AIP-123 used to test the behavior described in the CreateBookRequest message. See: https://google.aip.dev/123 18 | type Book struct { 19 | // Output only. The book's ID. 20 | Id string `json:"id,omitempty"` 21 | // Output only. Creation time of the book. 22 | CreateTime time.Time `json:"createTime,omitempty"` 23 | } 24 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_a_bit_of_everything_repeated.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbABitOfEverythingRepeated struct { 14 | PathRepeatedFloatValue []float32 `json:"pathRepeatedFloatValue,omitempty"` 15 | PathRepeatedDoubleValue []float64 `json:"pathRepeatedDoubleValue,omitempty"` 16 | PathRepeatedInt64Value []string `json:"pathRepeatedInt64Value,omitempty"` 17 | PathRepeatedUint64Value []string `json:"pathRepeatedUint64Value,omitempty"` 18 | PathRepeatedInt32Value []int32 `json:"pathRepeatedInt32Value,omitempty"` 19 | PathRepeatedFixed64Value []string `json:"pathRepeatedFixed64Value,omitempty"` 20 | PathRepeatedFixed32Value []int64 `json:"pathRepeatedFixed32Value,omitempty"` 21 | PathRepeatedBoolValue []bool `json:"pathRepeatedBoolValue,omitempty"` 22 | PathRepeatedStringValue []string `json:"pathRepeatedStringValue,omitempty"` 23 | PathRepeatedBytesValue []string `json:"pathRepeatedBytesValue,omitempty"` 24 | PathRepeatedUint32Value []int64 `json:"pathRepeatedUint32Value,omitempty"` 25 | PathRepeatedEnumValue []ExamplepbNumericEnum `json:"pathRepeatedEnumValue,omitempty"` 26 | PathRepeatedSfixed32Value []int32 `json:"pathRepeatedSfixed32Value,omitempty"` 27 | PathRepeatedSfixed64Value []string `json:"pathRepeatedSfixed64Value,omitempty"` 28 | PathRepeatedSint32Value []int32 `json:"pathRepeatedSint32Value,omitempty"` 29 | PathRepeatedSint64Value []string `json:"pathRepeatedSint64Value,omitempty"` 30 | } 31 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_bar.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbBar struct { 14 | Id string `json:"id"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_body.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbBody struct { 14 | Name string `json:"name,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_book.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | import ( 14 | "time" 15 | ) 16 | 17 | // An example resource type from AIP-123 used to test the behavior described in the CreateBookRequest message. See: https://google.aip.dev/123 18 | type ExamplepbBook struct { 19 | // The resource name of the book. Format: `publishers/{publisher}/books/{book}` Example: `publishers/1257894000000000000/books/my-book` 20 | Name string `json:"name,omitempty"` 21 | // Output only. The book's ID. 22 | Id string `json:"id,omitempty"` 23 | // Output only. Creation time of the book. 24 | CreateTime time.Time `json:"createTime,omitempty"` 25 | } 26 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_check_status_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbCheckStatusResponse struct { 14 | Status *RpcStatus `json:"status,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_error_object.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbErrorObject struct { 14 | // Response code 15 | Code int32 `json:"code,omitempty"` 16 | // Response message 17 | Message string `json:"message,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_error_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbErrorResponse struct { 14 | // Unique event identifier for server requests 15 | CorrelationId string `json:"correlationId,omitempty"` 16 | Error_ *ExamplepbErrorObject `json:"error,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_foo.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbFoo struct { 14 | Bar *ExamplepbBar `json:"bar"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_numeric_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | // ExamplepbNumericEnum : NumericEnum is one or zero. 13 | type ExamplepbNumericEnum string 14 | 15 | // List of examplepbNumericEnum 16 | const ( 17 | ZERO_ExamplepbNumericEnum ExamplepbNumericEnum = "ZERO" 18 | ONE_ExamplepbNumericEnum ExamplepbNumericEnum = "ONE" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_required_message_type_request.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbRequiredMessageTypeRequest struct { 14 | Id string `json:"id"` 15 | Foo *ProtoexamplepbFoo `json:"foo"` 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepb_snake_enum_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ExamplepbSnakeEnumResponse struct { 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepbsnake_case_0_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | // ExamplepbsnakeCase0Enum : - value_e: buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE - value_f: buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE 13 | type ExamplepbsnakeCase0Enum string 14 | 15 | // List of examplepbsnake_case_0_enum 16 | const ( 17 | E_ExamplepbsnakeCase0Enum ExamplepbsnakeCase0Enum = "value_e" 18 | F_ExamplepbsnakeCase0Enum ExamplepbsnakeCase0Enum = "value_f" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_examplepbsnake_case_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | // ExamplepbsnakeCaseEnum : - value_c: buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE - value_d: buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE 13 | type ExamplepbsnakeCaseEnum string 14 | 15 | // List of examplepbsnake_case_enum 16 | const ( 17 | C_ExamplepbsnakeCaseEnum ExamplepbsnakeCaseEnum = "value_c" 18 | D_ExamplepbsnakeCaseEnum ExamplepbsnakeCaseEnum = "value_d" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_message_path_enum_nested_path_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type MessagePathEnumNestedPathEnum string 14 | 15 | // List of MessagePathEnumNestedPathEnum 16 | const ( 17 | GHI_MessagePathEnumNestedPathEnum MessagePathEnumNestedPathEnum = "GHI" 18 | JKL_MessagePathEnumNestedPathEnum MessagePathEnumNestedPathEnum = "JKL" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_nested_deep_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | // NestedDeepEnum : DeepEnum is one or zero. - FALSE: FALSE is false. - TRUE: TRUE is true. 13 | type NestedDeepEnum string 14 | 15 | // List of NestedDeepEnum 16 | const ( 17 | FALSE_NestedDeepEnum NestedDeepEnum = "FALSE" 18 | TRUE_NestedDeepEnum NestedDeepEnum = "TRUE" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_oneofenum_example_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type OneofenumExampleEnum string 14 | 15 | // List of oneofenumExampleEnum 16 | const ( 17 | UNSPECIFIED_OneofenumExampleEnum OneofenumExampleEnum = "EXAMPLE_ENUM_UNSPECIFIED" 18 | FIRST_OneofenumExampleEnum OneofenumExampleEnum = "EXAMPLE_ENUM_FIRST" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_pathenum_path_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type PathenumPathEnum string 14 | 15 | // List of pathenumPathEnum 16 | const ( 17 | ABC_PathenumPathEnum PathenumPathEnum = "ABC" 18 | DEF_PathenumPathEnum PathenumPathEnum = "DEF" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_pathenumsnake_case_for_import.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | // PathenumsnakeCaseForImport : - value_x: buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE - value_y: buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE 13 | type PathenumsnakeCaseForImport string 14 | 15 | // List of pathenumsnake_case_for_import 16 | const ( 17 | X_PathenumsnakeCaseForImport PathenumsnakeCaseForImport = "value_x" 18 | Y_PathenumsnakeCaseForImport PathenumsnakeCaseForImport = "value_y" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_protoexamplepb_foo.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type ProtoexamplepbFoo struct { 14 | Bar *ExamplepbBar `json:"bar"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_rpc_status.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | // The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors). 14 | type RpcStatus struct { 15 | // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. 16 | Code int32 `json:"code,omitempty"` 17 | // A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. 18 | Message string `json:"message,omitempty"` 19 | // A list of messages that carry the error details. There is a common set of message types for APIs to use. 20 | Details []ProtobufAny `json:"details,omitempty"` 21 | } 22 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_sub_string_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type SubStringMessage struct { 14 | Value string `json:"value,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_the_book_to_update_.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | import ( 14 | "time" 15 | ) 16 | 17 | // The book's `name` field is used to identify the book to be updated. Format: publishers/{publisher}/books/{book} 18 | type TheBookToUpdate_ struct { 19 | // Output only. The book's ID. 20 | Id string `json:"id,omitempty"` 21 | // Output only. Creation time of the book. 22 | CreateTime time.Time `json:"createTime,omitempty"` 23 | } 24 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_the_book_to_update__1.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | package abe 11 | import ( 12 | "time" 13 | ) 14 | 15 | // The book's `name` field is used to identify the book to be updated. Format: publishers/{publisher}/books/{book} 16 | type TheBookToUpdate1 struct { 17 | // Output only. The book's ID. 18 | Id string `json:"id,omitempty"` 19 | // Output only. Creation time of the book. 20 | CreateTime time.Time `json:"createTime,omitempty"` 21 | } 22 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_the_book_to_update_the_books_name_field_is_used_to_identify_the_book_to_be_updated_format_publisherspublisherbooksbook.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | import ( 14 | "time" 15 | ) 16 | 17 | type TheBookToUpdateTheBooksNameFieldIsUsedToIdentifyTheBookToBeUpdatedFormatPublisherspublisherbooksbook struct { 18 | // Output only. The book's ID. 19 | Id string `json:"id,omitempty"` 20 | // Output only. Creation time of the book. 21 | CreateTime time.Time `json:"createTime,omitempty"` 22 | } 23 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_update_v2_request_request_for_update_includes_the_message_and_the_update_mask.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | type UpdateV2RequestRequestForUpdateIncludesTheMessageAndTheUpdateMask struct { 14 | Abe *ABitOfEverything4 `json:"abe,omitempty"` 15 | // The paths to update. 16 | UpdateMask string `json:"updateMask,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_update_v2_request_request_for_update_includes_the_message_and_the_update_mask_1.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | package abe 11 | 12 | type UpdateV2RequestRequestForUpdateIncludesTheMessageAndTheUpdateMask1 struct { 13 | Abe *ABitOfEverything8 `json:"abe,omitempty"` 14 | // The paths to update. 15 | UpdateMask string `json:"updateMask,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/model_v1exampledeep_pathsingle_nested_name_single_nested.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | // Nested is nested type. 14 | type V1exampledeepPathsingleNestedNameSingleNested struct { 15 | Amount int64 `json:"amount,omitempty"` 16 | // DeepEnum description. 17 | Ok *NestedDeepEnum `json:"ok,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /examples/internal/clients/abe/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A Bit of Everything 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package abe 12 | 13 | import ( 14 | "net/http" 15 | ) 16 | 17 | type APIResponse struct { 18 | *http.Response `json:"-"` 19 | Message string `json:"message,omitempty"` 20 | // Operation is the name of the swagger operation. 21 | Operation string `json:"operation,omitempty"` 22 | // RequestURL is the request URL. This value is always available, even if the 23 | // embedded *http.Response is nil. 24 | RequestURL string `json:"url,omitempty"` 25 | // Method is the HTTP method used for the request. This value is always 26 | // available, even if the embedded *http.Response is nil. 27 | Method string `json:"method,omitempty"` 28 | // Payload holds the contents of the response body (which may be nil or empty). 29 | // This is provided here as the raw response.Body() reader will have already 30 | // been drained. 31 | Payload []byte `json:"-"` 32 | } 33 | 34 | func NewAPIResponse(r *http.Response) *APIResponse { 35 | 36 | response := &APIResponse{Response: r} 37 | return response 38 | } 39 | 40 | func NewAPIResponseWithError(errorMessage string) *APIResponse { 41 | 42 | response := &APIResponse{Message: errorMessage} 43 | return response 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/.gitignore: -------------------------------------------------------------------------------- 1 | /docs 2 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | 2.4.8 -------------------------------------------------------------------------------- /examples/internal/clients/echo/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | go_library( 6 | name = "echo", 7 | srcs = [ 8 | "api_echo_service.go", 9 | "client.go", 10 | "configuration.go", 11 | "model_examplepb_dynamic_message.go", 12 | "model_examplepb_dynamic_message_update.go", 13 | "model_examplepb_embedded.go", 14 | "model_examplepb_nested_message.go", 15 | "model_examplepb_simple_message.go", 16 | "model_protobuf_any.go", 17 | "model_protobuf_null_value.go", 18 | "model_rpc_status.go", 19 | "response.go", 20 | ], 21 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/clients/echo", 22 | deps = [ 23 | "@com_github_antihax_optional//:optional", 24 | "@org_golang_x_oauth2//:oauth2", 25 | ], 26 | ) 27 | 28 | alias( 29 | name = "go_default_library", 30 | actual = ":echo", 31 | visibility = ["//examples:__subpackages__"], 32 | ) 33 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_examplepb_dynamic_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | // DynamicMessage represents a message which can have its structure built dynamically using Struct and Values. 13 | type ExamplepbDynamicMessage struct { 14 | StructField *interface{} `json:"structField,omitempty"` 15 | ValueField *interface{} `json:"valueField,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_examplepb_dynamic_message_update.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | type ExamplepbDynamicMessageUpdate struct { 13 | Body *ExamplepbDynamicMessage `json:"body,omitempty"` 14 | UpdateMask string `json:"updateMask,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_examplepb_embedded.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | // Embedded represents a message embedded in SimpleMessage. 13 | type ExamplepbEmbedded struct { 14 | Progress string `json:"progress,omitempty"` 15 | Note string `json:"note,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_examplepb_nested_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | type ExamplepbNestedMessage struct { 13 | NId string `json:"nId,omitempty"` 14 | Val string `json:"val,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_examplepb_simple_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | // SimpleMessage represents a simple message sent to the Echo service. 13 | type ExamplepbSimpleMessage struct { 14 | // Id represents the message identifier. 15 | Id string `json:"id,omitempty"` 16 | Num string `json:"num,omitempty"` 17 | LineNum string `json:"lineNum,omitempty"` 18 | Lang string `json:"lang,omitempty"` 19 | Status *ExamplepbEmbedded `json:"status,omitempty"` 20 | En string `json:"en,omitempty"` 21 | No *ExamplepbEmbedded `json:"no,omitempty"` 22 | ResourceId string `json:"resourceId,omitempty"` 23 | NId *ExamplepbNestedMessage `json:"nId,omitempty"` 24 | } 25 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_protobuf_null_value.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | // ProtobufNullValue : `NullValue` is a singleton enumeration to represent the null value for the `Value` type union. The JSON representation for `NullValue` is JSON `null`. - NULL_VALUE: Null value. 12 | type ProtobufNullValue string 13 | 14 | // List of protobufNullValue 15 | const ( 16 | NULL_VALUE_ProtobufNullValue ProtobufNullValue = "NULL_VALUE" 17 | ) 18 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/model_rpc_status.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | // The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors). 13 | type RpcStatus struct { 14 | // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. 15 | Code int32 `json:"code,omitempty"` 16 | // A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. 17 | Message string `json:"message,omitempty"` 18 | // A list of messages that carry the error details. There is a common set of message types for APIs to use. 19 | Details []ProtobufAny `json:"details,omitempty"` 20 | } 21 | -------------------------------------------------------------------------------- /examples/internal/clients/echo/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Echo Service 3 | * 4 | * Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package echo 11 | 12 | import ( 13 | "net/http" 14 | ) 15 | 16 | type APIResponse struct { 17 | *http.Response `json:"-"` 18 | Message string `json:"message,omitempty"` 19 | // Operation is the name of the swagger operation. 20 | Operation string `json:"operation,omitempty"` 21 | // RequestURL is the request URL. This value is always available, even if the 22 | // embedded *http.Response is nil. 23 | RequestURL string `json:"url,omitempty"` 24 | // Method is the HTTP method used for the request. This value is always 25 | // available, even if the embedded *http.Response is nil. 26 | Method string `json:"method,omitempty"` 27 | // Payload holds the contents of the response body (which may be nil or empty). 28 | // This is provided here as the raw response.Body() reader will have already 29 | // been drained. 30 | Payload []byte `json:"-"` 31 | } 32 | 33 | func NewAPIResponse(r *http.Response) *APIResponse { 34 | 35 | response := &APIResponse{Response: r} 36 | return response 37 | } 38 | 39 | func NewAPIResponseWithError(errorMessage string) *APIResponse { 40 | 41 | response := &APIResponse{Message: errorMessage} 42 | return response 43 | } 44 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/.gitignore: -------------------------------------------------------------------------------- 1 | /docs 2 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | 2.4.8 -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | go_library( 4 | name = "generateunboundmethods", 5 | srcs = [ 6 | "api_generate_unbound_methods_echo_service.go", 7 | "client.go", 8 | "configuration.go", 9 | "model_examplepb_generate_unbound_methods_simple_message.go", 10 | "model_protobuf_any.go", 11 | "model_rpc_status.go", 12 | "model_runtime_error.go", 13 | "response.go", 14 | ], 15 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/clients/generateunboundmethods", 16 | visibility = ["//examples:__subpackages__"], 17 | deps = ["@org_golang_x_oauth2//:oauth2"], 18 | ) 19 | 20 | alias( 21 | name = "go_default_library", 22 | actual = ":generateunboundmethods", 23 | visibility = ["//examples:__subpackages__"], 24 | ) 25 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/docs/ExamplepbGenerateUnboundMethodsSimpleMessage.md: -------------------------------------------------------------------------------- 1 | # ExamplepbGenerateUnboundMethodsSimpleMessage 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Id** | **string** | Id represents the message identifier. | [optional] [default to null] 7 | **Num** | **string** | | [optional] [default to null] 8 | **Duration** | **string** | | [optional] [default to null] 9 | 10 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/docs/ProtobufAny.md: -------------------------------------------------------------------------------- 1 | # ProtobufAny 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Type_** | **string** | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/docs/RuntimeError.md: -------------------------------------------------------------------------------- 1 | # RuntimeError 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Error_** | **string** | | [optional] [default to null] 7 | **Code** | **int32** | | [optional] [default to null] 8 | **Message** | **string** | | [optional] [default to null] 9 | **Details** | [**[]ProtobufAny**](protobufAny.md) | | [optional] [default to null] 10 | 11 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/model_examplepb_generate_unbound_methods_simple_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/generate_unbound_methods.proto 3 | * 4 | * Generate Unannotated Methods Echo Service Similar to echo_service.proto but without annotations and without external configuration. Generate Unannotated Methods Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package generateunboundmethods 11 | 12 | // GenerateUnboundMethodsSimpleMessage represents a simple message sent to the unannotated GenerateUnboundMethodsEchoService service. 13 | type ExamplepbGenerateUnboundMethodsSimpleMessage struct { 14 | // Id represents the message identifier. 15 | Id string `json:"id,omitempty"` 16 | Num string `json:"num,omitempty"` 17 | Duration string `json:"duration,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/model_protobuf_any.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/generate_unbound_methods.proto 3 | * 4 | * Generate Unannotated Methods Echo Service Similar to echo_service.proto but without annotations and without external configuration. Generate Unannotated Methods Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package generateunboundmethods 11 | 12 | type ProtobufAny struct { 13 | Type_ string `json:"@type,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/model_rpc_status.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/generate_unbound_methods.proto 3 | * 4 | * Generate Unannotated Methods Echo Service Similar to echo_service.proto but without annotations and without external configuration. Generate Unannotated Methods Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package generateunboundmethods 11 | 12 | type RpcStatus struct { 13 | Code int32 `json:"code,omitempty"` 14 | Message string `json:"message,omitempty"` 15 | Details []ProtobufAny `json:"details,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/model_runtime_error.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/generate_unbound_methods.proto 3 | * 4 | * Generate Unannotated Methods Echo Service Similar to echo_service.proto but without annotations and without external configuration. Generate Unannotated Methods Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package generateunboundmethods 11 | 12 | type RuntimeError struct { 13 | Error_ string `json:"error,omitempty"` 14 | Code int32 `json:"code,omitempty"` 15 | Message string `json:"message,omitempty"` 16 | Details []ProtobufAny `json:"details,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /examples/internal/clients/generateunboundmethods/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/generate_unbound_methods.proto 3 | * 4 | * Generate Unannotated Methods Echo Service Similar to echo_service.proto but without annotations and without external configuration. Generate Unannotated Methods Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package generateunboundmethods 11 | 12 | import ( 13 | "net/http" 14 | ) 15 | 16 | type APIResponse struct { 17 | *http.Response `json:"-"` 18 | Message string `json:"message,omitempty"` 19 | // Operation is the name of the swagger operation. 20 | Operation string `json:"operation,omitempty"` 21 | // RequestURL is the request URL. This value is always available, even if the 22 | // embedded *http.Response is nil. 23 | RequestURL string `json:"url,omitempty"` 24 | // Method is the HTTP method used for the request. This value is always 25 | // available, even if the embedded *http.Response is nil. 26 | Method string `json:"method,omitempty"` 27 | // Payload holds the contents of the response body (which may be nil or empty). 28 | // This is provided here as the raw response.Body() reader will have already 29 | // been drained. 30 | Payload []byte `json:"-"` 31 | } 32 | 33 | func NewAPIResponse(r *http.Response) *APIResponse { 34 | 35 | response := &APIResponse{Response: r} 36 | return response 37 | } 38 | 39 | func NewAPIResponseWithError(errorMessage string) *APIResponse { 40 | 41 | response := &APIResponse{Message: errorMessage} 42 | return response 43 | } 44 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | 2.4.8 -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | go_library( 4 | name = "responsebody", 5 | srcs = [ 6 | "api_response_body_service.go", 7 | "client.go", 8 | "configuration.go", 9 | "model_examplepb_repeated_response_body_out.go", 10 | "model_examplepb_repeated_response_body_out_response.go", 11 | "model_examplepb_repeated_response_strings.go", 12 | "model_examplepb_response_body_out.go", 13 | "model_examplepb_response_body_out_response.go", 14 | "model_examplepb_response_body_value.go", 15 | "model_protobuf_any.go", 16 | "model_response_response_type.go", 17 | "model_rpc_status.go", 18 | "model_stream_result_of_examplepb_response_body_out.go", 19 | "response.go", 20 | ], 21 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/clients/responsebody", 22 | visibility = ["//visibility:public"], 23 | deps = ["@org_golang_x_oauth2//:oauth2"], 24 | ) 25 | 26 | alias( 27 | name = "go_default_library", 28 | actual = ":responsebody", 29 | visibility = ["//examples:__subpackages__"], 30 | ) 31 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbRepeatedResponseBodyOut.md: -------------------------------------------------------------------------------- 1 | # ExamplepbRepeatedResponseBodyOut 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Response** | [**[]ExamplepbRepeatedResponseBodyOutResponse**](examplepbRepeatedResponseBodyOutResponse.md) | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbRepeatedResponseBodyOutResponse.md: -------------------------------------------------------------------------------- 1 | # ExamplepbRepeatedResponseBodyOutResponse 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Data** | **string** | | [optional] [default to null] 7 | **Type_** | [***ResponseResponseType**](ResponseResponseType.md) | | [optional] [default to null] 8 | 9 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbRepeatedResponseStrings.md: -------------------------------------------------------------------------------- 1 | # ExamplepbRepeatedResponseStrings 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Values** | **[]string** | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbResponseBodyMessage.md: -------------------------------------------------------------------------------- 1 | # ExamplepbResponseBodyMessage 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Request** | **string** | | [optional] [default to null] 7 | **Response** | [**ExamplepbResponseBodyMessageResponse**](examplepbResponseBodyMessageResponse.md) | | [optional] [default to null] 8 | 9 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbResponseBodyMessageResponse.md: -------------------------------------------------------------------------------- 1 | # ExamplepbResponseBodyMessageResponse 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Data** | **string** | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbResponseBodyOut.md: -------------------------------------------------------------------------------- 1 | # ExamplepbResponseBodyOut 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Response** | [***ExamplepbResponseBodyOutResponse**](examplepbResponseBodyOutResponse.md) | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbResponseBodyOutResponse.md: -------------------------------------------------------------------------------- 1 | # ExamplepbResponseBodyOutResponse 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Data** | **string** | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbResponseBodyReq.md: -------------------------------------------------------------------------------- 1 | # ExamplepbResponseBodyReq 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Data** | **string** | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ExamplepbResponseBodyValue.md: -------------------------------------------------------------------------------- 1 | # ExamplepbResponseBodyValue 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **ResponseBodyValue** | **string** | | [optional] [default to null] 7 | 8 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/ResponseResponseType.md: -------------------------------------------------------------------------------- 1 | # ResponseResponseType 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | 7 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/RpcStatus.md: -------------------------------------------------------------------------------- 1 | # RpcStatus 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Code** | **int32** | The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. | [optional] [default to null] 7 | **Message** | **string** | A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. | [optional] [default to null] 8 | **Details** | [**[]ProtobufAny**](protobufAny.md) | A list of messages that carry the error details. There is a common set of message types for APIs to use. | [optional] [default to null] 9 | 10 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/RuntimeError.md: -------------------------------------------------------------------------------- 1 | # RuntimeError 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Error_** | **string** | | [optional] [default to null] 7 | **Code** | **int32** | | [optional] [default to null] 8 | **Message** | **string** | | [optional] [default to null] 9 | **Details** | [**[]ProtobufAny**](protobufAny.md) | | [optional] [default to null] 10 | 11 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/docs/StreamResultOfExamplepbResponseBodyOut.md: -------------------------------------------------------------------------------- 1 | # StreamResultOfExamplepbResponseBodyOut 2 | 3 | ## Properties 4 | Name | Type | Description | Notes 5 | ------------ | ------------- | ------------- | ------------- 6 | **Result** | [***ExamplepbResponseBodyOutResponse**](examplepbResponseBodyOutResponse.md) | | [optional] [default to null] 7 | **Error_** | [***RpcStatus**](rpcStatus.md) | | [optional] [default to null] 8 | 9 | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_examplepb_repeated_response_body_out.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ExamplepbRepeatedResponseBodyOut struct { 13 | Response []ExamplepbRepeatedResponseBodyOutResponse `json:"response,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_examplepb_repeated_response_body_out_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ExamplepbRepeatedResponseBodyOutResponse struct { 13 | Data string `json:"data,omitempty"` 14 | Type_ *ResponseResponseType `json:"type,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_examplepb_repeated_response_strings.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ExamplepbRepeatedResponseStrings struct { 13 | Values []string `json:"values,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_examplepb_response_body_out.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ExamplepbResponseBodyOut struct { 13 | Response *ExamplepbResponseBodyOutResponse `json:"response,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_examplepb_response_body_out_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ExamplepbResponseBodyOutResponse struct { 13 | Data string `json:"data,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_examplepb_response_body_value.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ExamplepbResponseBodyValue struct { 13 | ResponseBodyValue string `json:"responseBodyValue,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_response_response_type.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type ResponseResponseType string 13 | 14 | // List of ResponseResponseType 15 | const ( 16 | UNKNOWN_ResponseResponseType ResponseResponseType = "UNKNOWN" 17 | A_ResponseResponseType ResponseResponseType = "A" 18 | B_ResponseResponseType ResponseResponseType = "B" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_rpc_status.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | // The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors). 13 | type RpcStatus struct { 14 | // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. 15 | Code int32 `json:"code,omitempty"` 16 | // A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. 17 | Message string `json:"message,omitempty"` 18 | // A list of messages that carry the error details. There is a common set of message types for APIs to use. 19 | Details []ProtobufAny `json:"details,omitempty"` 20 | } 21 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/model_stream_result_of_examplepb_response_body_out.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | type StreamResultOfExamplepbResponseBodyOut struct { 13 | Result *ExamplepbResponseBodyOutResponse `json:"result,omitempty"` 14 | Error_ *RpcStatus `json:"error,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/responsebody/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * examples/internal/proto/examplepb/response_body_service.proto 3 | * 4 | * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) 5 | * 6 | * API version: version not set 7 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 8 | */ 9 | 10 | package responsebody 11 | 12 | import ( 13 | "net/http" 14 | ) 15 | 16 | type APIResponse struct { 17 | *http.Response `json:"-"` 18 | Message string `json:"message,omitempty"` 19 | // Operation is the name of the swagger operation. 20 | Operation string `json:"operation,omitempty"` 21 | // RequestURL is the request URL. This value is always available, even if the 22 | // embedded *http.Response is nil. 23 | RequestURL string `json:"url,omitempty"` 24 | // Method is the HTTP method used for the request. This value is always 25 | // available, even if the embedded *http.Response is nil. 26 | Method string `json:"method,omitempty"` 27 | // Payload holds the contents of the response body (which may be nil or empty). 28 | // This is provided here as the raw response.Body() reader will have already 29 | // been drained. 30 | Payload []byte `json:"-"` 31 | } 32 | 33 | func NewAPIResponse(r *http.Response) *APIResponse { 34 | 35 | response := &APIResponse{Response: r} 36 | return response 37 | } 38 | 39 | func NewAPIResponseWithError(errorMessage string) *APIResponse { 40 | 41 | response := &APIResponse{Message: errorMessage} 42 | return response 43 | } 44 | -------------------------------------------------------------------------------- /examples/internal/clients/staticcheck.conf: -------------------------------------------------------------------------------- 1 | checks = ["-all"] 2 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/.gitignore: -------------------------------------------------------------------------------- 1 | /docs 2 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | 2.4.8 -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | go_library( 6 | name = "unannotatedecho", 7 | srcs = [ 8 | "api_unannotated_echo_service.go", 9 | "client.go", 10 | "configuration.go", 11 | "model_examplepb_numeric_enum.go", 12 | "model_examplepb_unannotated_embedded.go", 13 | "model_examplepb_unannotated_nested_message.go", 14 | "model_examplepb_unannotated_simple_message.go", 15 | "model_protobuf_any.go", 16 | "model_rpc_status.go", 17 | "response.go", 18 | ], 19 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/clients/unannotatedecho", 20 | deps = [ 21 | "@com_github_antihax_optional//:optional", 22 | "@org_golang_x_oauth2//:oauth2", 23 | ], 24 | ) 25 | 26 | alias( 27 | name = "go_default_library", 28 | actual = ":unannotatedecho", 29 | visibility = ["//examples:__subpackages__"], 30 | ) 31 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/model_examplepb_numeric_enum.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | // ExamplepbNumericEnum : NumericEnum is one or zero. - ZERO: ZERO means 0 - ONE: ONE means 1 13 | type ExamplepbNumericEnum string 14 | 15 | // List of examplepbNumericEnum 16 | const ( 17 | ZERO_ExamplepbNumericEnum ExamplepbNumericEnum = "ZERO" 18 | ONE_ExamplepbNumericEnum ExamplepbNumericEnum = "ONE" 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/model_examplepb_unannotated_embedded.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | 13 | // Embedded represents a message embedded in SimpleMessage. 14 | type ExamplepbUnannotatedEmbedded struct { 15 | Progress string `json:"progress,omitempty"` 16 | Note string `json:"note,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/model_examplepb_unannotated_nested_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | 13 | type ExamplepbUnannotatedNestedMessage struct { 14 | NId string `json:"nId,omitempty"` 15 | Val string `json:"val,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/model_examplepb_unannotated_simple_message.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | 13 | // A simple message with many types 14 | type ExamplepbUnannotatedSimpleMessage struct { 15 | // Id represents the message identifier. 16 | Id string `json:"id"` 17 | // Int value field 18 | Num string `json:"num"` 19 | Duration string `json:"duration,omitempty"` 20 | LineNum string `json:"lineNum,omitempty"` 21 | Lang string `json:"lang,omitempty"` 22 | Status *ExamplepbUnannotatedEmbedded `json:"status,omitempty"` 23 | En string `json:"en,omitempty"` 24 | No *ExamplepbUnannotatedEmbedded `json:"no,omitempty"` 25 | ResourceId string `json:"resourceId,omitempty"` 26 | NId *ExamplepbUnannotatedNestedMessage `json:"nId,omitempty"` 27 | } 28 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/model_protobuf_any.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | 13 | type ProtobufAny struct { 14 | Type_ string `json:"@type,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/model_rpc_status.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | 13 | type RpcStatus struct { 14 | Code int32 `json:"code,omitempty"` 15 | Message string `json:"message,omitempty"` 16 | Details []ProtobufAny `json:"details,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /examples/internal/clients/unannotatedecho/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Unannotated Echo 3 | * 4 | * Unannotated Echo Service Similar to echo_service.proto but without annotations. See unannotated_echo_service.yaml for the equivalent of the annotations in gRPC API configuration format. Echo Service API consists of a single service which returns a message. 5 | * 6 | * API version: 1.0 7 | * Contact: none@example.com 8 | * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) 9 | */ 10 | 11 | package unannotatedecho 12 | 13 | import ( 14 | "net/http" 15 | ) 16 | 17 | type APIResponse struct { 18 | *http.Response `json:"-"` 19 | Message string `json:"message,omitempty"` 20 | // Operation is the name of the swagger operation. 21 | Operation string `json:"operation,omitempty"` 22 | // RequestURL is the request URL. This value is always available, even if the 23 | // embedded *http.Response is nil. 24 | RequestURL string `json:"url,omitempty"` 25 | // Method is the HTTP method used for the request. This value is always 26 | // available, even if the embedded *http.Response is nil. 27 | Method string `json:"method,omitempty"` 28 | // Payload holds the contents of the response body (which may be nil or empty). 29 | // This is provided here as the raw response.Body() reader will have already 30 | // been drained. 31 | Payload []byte `json:"-"` 32 | } 33 | 34 | func NewAPIResponse(r *http.Response) *APIResponse { 35 | 36 | response := &APIResponse{Response: r} 37 | return response 38 | } 39 | 40 | func NewAPIResponseWithError(errorMessage string) *APIResponse { 41 | 42 | response := &APIResponse{Message: errorMessage} 43 | return response 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/cmd/example-gateway-server/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") 2 | 3 | go_library( 4 | name = "example-gateway-server_lib", 5 | srcs = ["main.go"], 6 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/cmd/example-gateway-server", 7 | visibility = ["//visibility:private"], 8 | deps = [ 9 | "//examples/internal/gateway", 10 | "@org_golang_google_grpc//grpclog", 11 | ], 12 | ) 13 | 14 | go_binary( 15 | name = "example-gateway-server", 16 | embed = [":example-gateway-server_lib"], 17 | visibility = ["//visibility:public"], 18 | ) 19 | -------------------------------------------------------------------------------- /examples/internal/cmd/example-gateway-server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Command example-gateway-server is an example reverse-proxy implementation 3 | whose HTTP handler is generated by grpc-gateway. 4 | */ 5 | package main 6 | 7 | import ( 8 | "context" 9 | "flag" 10 | 11 | "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/gateway" 12 | "google.golang.org/grpc/grpclog" 13 | ) 14 | 15 | var ( 16 | endpoint = flag.String("endpoint", "localhost:9090", "endpoint of the gRPC service") 17 | network = flag.String("network", "tcp", `one of "tcp" or "unix". Must be consistent to -endpoint`) 18 | openAPIDir = flag.String("openapi_dir", "examples/internal/proto/examplepb", "path to the directory which contains OpenAPI definitions") 19 | ) 20 | 21 | func main() { 22 | flag.Parse() 23 | 24 | ctx := context.Background() 25 | opts := gateway.Options{ 26 | Addr: ":8080", 27 | GRPCServer: gateway.Endpoint{ 28 | Network: *network, 29 | Addr: *endpoint, 30 | }, 31 | OpenAPIDir: *openAPIDir, 32 | } 33 | if err := gateway.Run(ctx, opts); err != nil { 34 | grpclog.Fatal(err) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/internal/cmd/example-grpc-server/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") 2 | 3 | package(default_visibility = ["//visibility:private"]) 4 | 5 | go_library( 6 | name = "example-grpc-server_lib", 7 | srcs = ["main.go"], 8 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/cmd/example-grpc-server", 9 | deps = [ 10 | "//examples/internal/server", 11 | "@org_golang_google_grpc//grpclog", 12 | ], 13 | ) 14 | 15 | go_binary( 16 | name = "example-server", 17 | embed = [":example-grpc-server_lib"], 18 | visibility = ["//visibility:public"], 19 | ) 20 | -------------------------------------------------------------------------------- /examples/internal/cmd/example-grpc-server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Command example-grpc-server is an example grpc server 3 | to be called by example-gateway-server. 4 | */ 5 | package main 6 | 7 | import ( 8 | "context" 9 | "flag" 10 | 11 | "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/server" 12 | "google.golang.org/grpc/grpclog" 13 | ) 14 | 15 | var ( 16 | addr = flag.String("addr", ":9090", "endpoint of the gRPC service") 17 | network = flag.String("network", "tcp", "a valid network type which is consistent to -addr") 18 | ) 19 | 20 | func main() { 21 | flag.Parse() 22 | 23 | ctx := context.Background() 24 | if err := server.Run(ctx, *network, *addr); err != nil { 25 | grpclog.Fatal(err) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/internal/gateway/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | go_library( 4 | name = "gateway", 5 | srcs = [ 6 | "doc.go", 7 | "gateway.go", 8 | "handlers.go", 9 | "main.go", 10 | ], 11 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/gateway", 12 | visibility = ["//visibility:public"], 13 | deps = [ 14 | "//examples/internal/proto/examplepb", 15 | "//examples/internal/proto/standalone", 16 | "//runtime", 17 | "@org_golang_google_genproto_googleapis_rpc//errdetails", 18 | "@org_golang_google_grpc//:grpc", 19 | "@org_golang_google_grpc//connectivity", 20 | "@org_golang_google_grpc//credentials/insecure", 21 | "@org_golang_google_grpc//grpclog", 22 | "@org_golang_google_protobuf//types/known/emptypb", 23 | ], 24 | ) 25 | 26 | alias( 27 | name = "go_default_library", 28 | actual = ":gateway", 29 | visibility = ["//examples:__subpackages__"], 30 | ) 31 | -------------------------------------------------------------------------------- /examples/internal/gateway/doc.go: -------------------------------------------------------------------------------- 1 | // Package gateway is an example of gRPC-Gateway server 2 | package gateway 3 | -------------------------------------------------------------------------------- /examples/internal/helloworld/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | # gazelle:exclude helloworld.pb.gw.go 6 | # gazelle:exclude helloworld_grpc.pb.go 7 | # gazelle:go_grpc_compilers //:go_apiv2, //:go_grpc, //protoc-gen-grpc-gateway:go_gen_grpc_gateway 8 | 9 | proto_library( 10 | name = "helloworld_proto", 11 | srcs = ["helloworld.proto"], 12 | visibility = ["//visibility:public"], 13 | deps = [ 14 | "@com_google_protobuf//:wrappers_proto", 15 | "@googleapis//google/api:annotations_proto", 16 | ], 17 | ) 18 | 19 | go_proto_library( 20 | name = "helloworld_go_proto", 21 | compilers = [ 22 | "//:go_apiv2", 23 | "//:go_grpc", 24 | "//protoc-gen-grpc-gateway:go_gen_grpc_gateway", 25 | ], 26 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/helloworld", 27 | proto = ":helloworld_proto", 28 | visibility = ["//visibility:public"], 29 | deps = [ 30 | "@org_golang_google_genproto_googleapis_api//annotations", 31 | ], 32 | ) 33 | 34 | go_library( 35 | name = "helloworld", 36 | embed = [":helloworld_go_proto"], 37 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/helloworld", 38 | visibility = ["//examples:__subpackages__"], 39 | ) 40 | 41 | alias( 42 | name = "go_default_library", 43 | actual = ":helloworld", 44 | visibility = ["//examples:__subpackages__"], 45 | ) 46 | -------------------------------------------------------------------------------- /examples/internal/helloworld/helloworld.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.helloworld; 4 | 5 | import "google/api/annotations.proto"; 6 | import "google/protobuf/wrappers.proto"; 7 | 8 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/helloworld"; 9 | 10 | service Greeter { 11 | rpc SayHello(HelloRequest) returns (HelloReply) { 12 | option (google.api.http) = { 13 | get: "/say/{name}" 14 | additional_bindings: {get: "/say/strval/{strVal}"} 15 | additional_bindings: {get: "/say/floatval/{floatVal}"} 16 | additional_bindings: {get: "/say/doubleval/{doubleVal}"} 17 | additional_bindings: {get: "/say/boolval/{boolVal}"} 18 | additional_bindings: {get: "/say/bytesval/{bytesVal}"} 19 | additional_bindings: {get: "/say/int32val/{int32Val}"} 20 | additional_bindings: {get: "/say/uint32val/{uint32Val}"} 21 | additional_bindings: {get: "/say/int64val/{int64Val}"} 22 | additional_bindings: {get: "/say/uint64val/{uint64Val}"} 23 | }; 24 | } 25 | } 26 | 27 | message HelloRequest { 28 | string name = 1; 29 | google.protobuf.StringValue strVal = 2; 30 | google.protobuf.FloatValue floatVal = 3; 31 | google.protobuf.DoubleValue doubleVal = 4; 32 | google.protobuf.BoolValue boolVal = 5; 33 | google.protobuf.BytesValue bytesVal = 6; 34 | google.protobuf.Int32Value int32Val = 7; 35 | google.protobuf.UInt32Value uint32Val = 8; 36 | google.protobuf.Int64Value int64Val = 9; 37 | google.protobuf.UInt64Value uint64Val = 10; 38 | } 39 | 40 | message HelloReply { 41 | string message = 1; 42 | } 43 | -------------------------------------------------------------------------------- /examples/internal/integration/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_test") 2 | 3 | go_test( 4 | name = "integration_test", 5 | srcs = [ 6 | "client_test.go", 7 | "integration_test.go", 8 | "main_test.go", 9 | ], 10 | deps = [ 11 | "//examples/internal/clients/abe", 12 | "//examples/internal/clients/echo", 13 | "//examples/internal/clients/unannotatedecho", 14 | "//examples/internal/gateway", 15 | "//examples/internal/proto/examplepb", 16 | "//examples/internal/proto/pathenum", 17 | "//examples/internal/proto/sub", 18 | "//examples/internal/server", 19 | "//runtime", 20 | "@com_github_google_go_cmp//cmp", 21 | "@com_github_rogpeppe_fastuuid//:fastuuid", 22 | "@org_golang_google_genproto_googleapis_rpc//status", 23 | "@org_golang_google_grpc//codes", 24 | "@org_golang_google_grpc//grpclog", 25 | "@org_golang_google_protobuf//encoding/protojson", 26 | "@org_golang_google_protobuf//proto", 27 | "@org_golang_google_protobuf//testing/protocmp", 28 | "@org_golang_google_protobuf//types/known/emptypb", 29 | "@org_golang_google_protobuf//types/known/fieldmaskpb", 30 | "@org_golang_google_protobuf//types/known/structpb", 31 | ], 32 | ) 33 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/enum_with_single_value.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - omit_enum_default_value=true 7 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/enum_with_single_value.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.examplepb; 4 | 5 | import "google/api/annotations.proto"; 6 | 7 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 8 | 9 | service EnumWithSingleValueService { 10 | rpc Echo(EnumWithSingleValueServiceEchoRequest) returns (EnumWithSingleValueServiceEchoResponse) { 11 | option (google.api.http) = { 12 | post: "/v1/example/enum-with-single-value/echo" 13 | body: "*" 14 | }; 15 | } 16 | } 17 | 18 | // EnumWithSingleValue is an enum with a single value. Since it has just a single value 19 | // the `enum` field should be omitted in the generated OpenAPI spec for the type when 20 | // the omit_enum_default_value option is set to true. 21 | enum EnumWithSingleValue { 22 | ENUM_WITH_SINGLE_VALUE_UNSPECIFIED = 0; 23 | } 24 | 25 | message EnumWithSingleValueServiceEchoRequest { 26 | EnumWithSingleValue value = 1; 27 | } 28 | 29 | message EnumWithSingleValueServiceEchoResponse {} 30 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/excess_body.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // Excess Body Service 4 | // Used to test server context cancellation with Unary and ServerStream methods 5 | // when client sends more data than expected. 6 | package grpc.gateway.examples.internal.proto.examplepb; 7 | 8 | import "google/api/annotations.proto"; 9 | import "google/protobuf/empty.proto"; 10 | 11 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 12 | 13 | service ExcessBodyService { 14 | rpc NoBodyRpc(google.protobuf.Empty) returns (google.protobuf.Empty) { 15 | option (google.api.http) = {post: "/rpc/excess-body/rpc"}; 16 | } 17 | rpc NoBodyServerStream(google.protobuf.Empty) returns (stream google.protobuf.Empty) { 18 | option (google.api.http) = {post: "/rpc/excess-body/stream"}; 19 | } 20 | rpc WithBodyRpc(google.protobuf.Empty) returns (google.protobuf.Empty) { 21 | option (google.api.http) = { 22 | post: "/rpc/excess-body/rpc/with-body" 23 | body: "*" 24 | }; 25 | } 26 | rpc WithBodyServerStream(google.protobuf.Empty) returns (stream google.protobuf.Empty) { 27 | option (google.api.http) = { 28 | post: "/rpc/excess-body/stream/with-body" 29 | body: "*" 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/generate_unbound_methods.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: grpc-gateway 4 | out: . 5 | opt: 6 | - paths=source_relative 7 | - generate_unbound_methods=true 8 | - plugin: openapiv2 9 | out: . 10 | opt: 11 | - generate_unbound_methods=true 12 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/generate_unbound_methods.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // Generate Unannotated Methods Echo Service 4 | // Similar to echo_service.proto but without annotations and without external configuration. 5 | // 6 | // Generate Unannotated Methods Echo Service API consists of a single service which returns 7 | // a message. 8 | package grpc.gateway.examples.internal.proto.examplepb; 9 | 10 | // Do not need annotations.proto, can still use well known types as usual 11 | import "google/protobuf/duration.proto"; 12 | 13 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 14 | 15 | // GenerateUnboundMethodsSimpleMessage represents a simple message sent to the unannotated GenerateUnboundMethodsEchoService service. 16 | message GenerateUnboundMethodsSimpleMessage { 17 | // Id represents the message identifier. 18 | string id = 1; 19 | int64 num = 2; 20 | google.protobuf.Duration duration = 3; 21 | } 22 | 23 | // GenerateUnboundMethodsEchoService service responds to incoming echo requests. 24 | service GenerateUnboundMethodsEchoService { 25 | // Echo method receives a simple message and returns it. 26 | // 27 | // The message posted as the id parameter will also be 28 | // returned. 29 | rpc Echo(GenerateUnboundMethodsSimpleMessage) returns (GenerateUnboundMethodsSimpleMessage); 30 | 31 | // EchoBody method receives a simple message and returns it. 32 | rpc EchoBody(GenerateUnboundMethodsSimpleMessage) returns (GenerateUnboundMethodsSimpleMessage); 33 | 34 | // EchoDelete method receives a simple message and returns it. 35 | rpc EchoDelete(GenerateUnboundMethodsSimpleMessage) returns (GenerateUnboundMethodsSimpleMessage); 36 | } 37 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/generated_input.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.examplepb; 4 | 5 | import "examples/internal/proto/examplepb/a_bit_of_everything.proto"; 6 | import "google/api/annotations.proto"; 7 | import "google/protobuf/empty.proto"; 8 | 9 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 10 | 11 | // This file is run through a genrule. 12 | 13 | // Defines some more operations to be added to ABitOfEverythingService 14 | service GeneratedService { 15 | rpc Create(ABitOfEverything) returns (google.protobuf.Empty) { 16 | option (google.api.http) = { 17 | post: "/v1/example/a_bit_of_everything/generated_create" 18 | body: "*" 19 | }; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/ignore_comment.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - ignore_comments=true 7 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/ignore_comment.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.examplepb; 4 | 5 | import "google/api/annotations.proto"; 6 | import "protoc-gen-openapiv2/options/annotations.proto"; 7 | 8 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 9 | 10 | // This comment should be excluded from OpenAPI output 11 | service FooService { 12 | // This comment should be excluded from OpenAPI output 13 | rpc Foo(FooRequest) returns (FooReply) { 14 | option (google.api.http) = { 15 | post: "/v1/example/foo" 16 | body: "*" 17 | }; 18 | } 19 | } 20 | 21 | // This comment should be excluded from OpenAPI output 22 | message FooRequest { 23 | // This comment should be excluded from OpenAPI output 24 | string username = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "This annotation should be preserved"}]; 25 | // This comment should be excluded from OpenAPI output 26 | string password = 2 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {title: "This annotation should be preserved"}]; 27 | } 28 | 29 | // This comment should be excluded from OpenAPI output 30 | message FooReply {} 31 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/openapi_merge.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - allow_merge=true 7 | - merge_file_name=examples/internal/proto/examplepb/openapi_merge 8 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/openapi_merge_b.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // Merging Services 4 | // 5 | // This is an example of merging two proto files. 6 | package grpc.gateway.examples.internal.examplepb; 7 | 8 | import "google/api/annotations.proto"; 9 | 10 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 11 | 12 | // InMessageB represents a message to ServiceB. 13 | message InMessageB { 14 | // Here is the explanation about InMessageB.values 15 | string value = 1; 16 | } 17 | 18 | // OutMessageB represents a message returned from ServiceB. 19 | message OutMessageB { 20 | // Here is the explanation about OutMessageB.value 21 | repeated string values = 1; 22 | } 23 | 24 | // ServiceB service responds to incoming merge requests. 25 | service ServiceB { 26 | // ServiceB.MethodOne receives InMessageB and returns OutMessageB 27 | // 28 | // Here is the detail explanation about ServiceB.MethodOne. 29 | rpc MethodOne(InMessageB) returns (OutMessageB) { 30 | option (google.api.http) = { 31 | post: "/v1/example/b/1" 32 | body: "*" 33 | }; 34 | } 35 | // ServiceB.MethodTwo receives OutMessageB and returns InMessageB 36 | // 37 | // Here is the detail explanation about ServiceB.MethodTwo. 38 | rpc MethodTwo(OutMessageB) returns (InMessageB) { 39 | option (google.api.http) = { 40 | post: "/v1/example/b/2" 41 | body: "*" 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/remove_internal_comment.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - remove_internal_comments=true 7 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/remove_internal_comment.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.examplepb; 4 | 5 | import "google/api/annotations.proto"; 6 | 7 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 8 | 9 | // Foo2Service (-- This comment should be excluded from OpenAPI output --) 10 | service Foo2Service { 11 | // Foo Summary (-- This comment should be excluded from OpenAPI output --) 12 | // 13 | // (-- This comment should be excluded from OpenAPI output --) 14 | // Description 15 | rpc Foo2(Foo2Request) returns (Foo2Reply) { 16 | option (google.api.http) = { 17 | post: "/v1/example/foo" 18 | body: "*" 19 | }; 20 | } 21 | } 22 | 23 | // Foo2Request (-- This comment should be excluded from OpenAPI output --) 24 | message Foo2Request { 25 | // Username. 26 | // (-- This comment should be excluded 27 | // from OpenAPI output --) 28 | // Same row, single line break doesn't count on markdown. 29 | string username = 1; 30 | // Password. 31 | // (-- This comment should be excluded 32 | // from OpenAPI output --) 33 | // 34 | // New row. 35 | string password = 2; 36 | } 37 | 38 | // (-- This comment should be excluded from OpenAPI output --) 39 | message Foo2Reply {} 40 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/standalone_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: grpc-gateway 4 | out: . 5 | opt: 6 | - paths=source_relative 7 | - standalone=true 8 | - grpc_api_configuration=examples/internal/proto/examplepb/standalone_echo_service.yaml 9 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/standalone_echo_service.yaml: -------------------------------------------------------------------------------- 1 | type: google.api.Service 2 | config_version: 3 3 | 4 | http: 5 | rules: 6 | - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo 7 | post: "/v2/example/echo/{id}" 8 | additional_bindings: 9 | - get: "/v2/example/echo/{id}/{num}" 10 | - get: "/v2/example/echo/{id}/{num}/{lang}" 11 | - get: "/v2/example/echo1/{id}/{line_num}/{status.note}" 12 | - get: "/v2/example/echo2/{no.note}" 13 | - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoBody 14 | post: "/v2/example/echo_body" 15 | body: "*" 16 | - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoDelete 17 | delete: "/v2/example/echo_delete" 18 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/stream.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.examplepb; 4 | 5 | import "examples/internal/proto/examplepb/a_bit_of_everything.proto"; 6 | import "examples/internal/proto/sub/message.proto"; 7 | import "google/api/annotations.proto"; 8 | import "google/api/httpbody.proto"; 9 | import "google/protobuf/duration.proto"; 10 | import "google/protobuf/empty.proto"; 11 | 12 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb"; 13 | 14 | // Defines some more operations to be added to ABitOfEverythingService 15 | service StreamService { 16 | rpc BulkCreate(stream ABitOfEverything) returns (google.protobuf.Empty) { 17 | option (google.api.http) = { 18 | post: "/v1/example/a_bit_of_everything/bulk" 19 | body: "*" 20 | }; 21 | } 22 | rpc List(Options) returns (stream ABitOfEverything) { 23 | option (google.api.http) = {get: "/v1/example/a_bit_of_everything"}; 24 | } 25 | rpc BulkEcho(stream grpc.gateway.examples.internal.proto.sub.StringMessage) returns (stream grpc.gateway.examples.internal.proto.sub.StringMessage) { 26 | option (google.api.http) = { 27 | post: "/v1/example/a_bit_of_everything/echo" 28 | body: "*" 29 | }; 30 | } 31 | rpc BulkEchoDuration(stream google.protobuf.Duration) returns (stream google.protobuf.Duration) { 32 | option (google.api.http) = { 33 | post: "/v1/example/a_bit_of_everything/echo_duration" 34 | body: "*" 35 | }; 36 | } 37 | 38 | rpc Download(Options) returns (stream google.api.HttpBody) { 39 | option (google.api.http) = {get: "/v1/example/download"}; 40 | } 41 | } 42 | 43 | message Options { 44 | bool error = 1; 45 | } 46 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/unannotated_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: grpc-gateway 4 | out: . 5 | opt: 6 | - paths=source_relative 7 | - grpc_api_configuration=examples/internal/proto/examplepb/unannotated_echo_service.yaml 8 | - plugin: openapiv2 9 | out: . 10 | opt: 11 | - grpc_api_configuration=examples/internal/proto/examplepb/unannotated_echo_service.yaml 12 | - openapi_configuration=examples/internal/proto/examplepb/unannotated_echo_service.swagger.yaml 13 | - generate_x_go_type=true 14 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/unannotated_echo_service.yaml: -------------------------------------------------------------------------------- 1 | type: google.api.Service 2 | config_version: 3 3 | 4 | http: 5 | rules: 6 | - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo 7 | post: "/v1/example/echo/{id}" 8 | additional_bindings: 9 | - get: "/v1/example/echo/{id}/{num}" 10 | - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoBody 11 | post: "/v1/example/echo_body" 12 | body: "*" 13 | - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoDelete 14 | delete: "/v1/example/echo_delete" 15 | 16 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/use_go_template.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - use_go_templates=true 7 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/visibility_rule_enums_as_ints_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - enums_as_ints=true 7 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/visibility_rule_internal_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - visibility_restriction_selectors=INTERNAL 7 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/visibility_rule_none_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/visibility_rule_preview_and_internal_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - visibility_restriction_selectors=PREVIEW 7 | - visibility_restriction_selectors=INTERNAL 8 | -------------------------------------------------------------------------------- /examples/internal/proto/examplepb/visibility_rule_preview_echo_service.buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - local: protoc-gen-openapiv2 4 | out: . 5 | opt: 6 | - visibility_restriction_selectors=PREVIEW 7 | -------------------------------------------------------------------------------- /examples/internal/proto/oneofenum/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | proto_library( 8 | name = "oneofenum_proto", 9 | srcs = ["oneof_enum.proto"], 10 | ) 11 | 12 | go_proto_library( 13 | name = "oneofenum_go_proto", 14 | compilers = ["//:go_apiv2"], 15 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/oneofenum", 16 | proto = ":oneofenum_proto", 17 | ) 18 | 19 | go_library( 20 | name = "oneofenum", 21 | embed = [":oneofenum_go_proto"], 22 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/oneofenum", 23 | ) 24 | 25 | alias( 26 | name = "go_default_library", 27 | actual = ":oneofenum", 28 | visibility = ["//examples:__subpackages__"], 29 | ) 30 | -------------------------------------------------------------------------------- /examples/internal/proto/oneofenum/oneof_enum.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.oneofenum; 4 | 5 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/oneofenum"; 6 | 7 | enum ExampleEnum { 8 | EXAMPLE_ENUM_UNSPECIFIED = 0; 9 | EXAMPLE_ENUM_FIRST = 1; 10 | } 11 | 12 | message OneofEnumMessage { 13 | oneof one { 14 | ExampleEnum example_enum = 1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/internal/proto/oneofenum/oneof_enum.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "examples/internal/proto/oneofenum/oneof_enum.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "@type": { 19 | "type": "string" 20 | } 21 | }, 22 | "additionalProperties": {} 23 | }, 24 | "rpcStatus": { 25 | "type": "object", 26 | "properties": { 27 | "code": { 28 | "type": "integer", 29 | "format": "int32" 30 | }, 31 | "message": { 32 | "type": "string" 33 | }, 34 | "details": { 35 | "type": "array", 36 | "items": { 37 | "type": "object", 38 | "$ref": "#/definitions/protobufAny" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/proto/pathenum/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | proto_library( 8 | name = "pathenum_proto", 9 | srcs = ["path_enum.proto"], 10 | ) 11 | 12 | go_proto_library( 13 | name = "pathenum_go_proto", 14 | compilers = ["//:go_apiv2"], 15 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/pathenum", 16 | proto = ":pathenum_proto", 17 | ) 18 | 19 | go_library( 20 | name = "pathenum", 21 | embed = [":pathenum_go_proto"], 22 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/pathenum", 23 | ) 24 | 25 | alias( 26 | name = "go_default_library", 27 | actual = ":pathenum", 28 | visibility = ["//examples:__subpackages__"], 29 | ) 30 | -------------------------------------------------------------------------------- /examples/internal/proto/pathenum/path_enum.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.pathenum; 4 | 5 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/pathenum"; 6 | 7 | enum PathEnum { 8 | ABC = 0; 9 | DEF = 1; 10 | } 11 | 12 | message MessagePathEnum { 13 | enum NestedPathEnum { 14 | GHI = 0; 15 | JKL = 1; 16 | } 17 | } 18 | 19 | message MessageWithPathEnum { 20 | PathEnum value = 1; 21 | } 22 | 23 | message MessageWithNestedPathEnum { 24 | MessagePathEnum.NestedPathEnum value = 1; 25 | } 26 | 27 | // Ignoring lint warnings as this enum type exist to validate proper functionality 28 | // for projects that don't follow these lint rules. 29 | // buf:lint:ignore ENUM_PASCAL_CASE 30 | enum snake_case_for_import { 31 | // buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE 32 | value_x = 0; 33 | // buf:lint:ignore ENUM_VALUE_UPPER_SNAKE_CASE 34 | value_y = 1; 35 | } 36 | -------------------------------------------------------------------------------- /examples/internal/proto/pathenum/path_enum.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "examples/internal/proto/pathenum/path_enum.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "@type": { 19 | "type": "string" 20 | } 21 | }, 22 | "additionalProperties": {} 23 | }, 24 | "rpcStatus": { 25 | "type": "object", 26 | "properties": { 27 | "code": { 28 | "type": "integer", 29 | "format": "int32" 30 | }, 31 | "message": { 32 | "type": "string" 33 | }, 34 | "details": { 35 | "type": "array", 36 | "items": { 37 | "type": "object", 38 | "$ref": "#/definitions/protobufAny" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/proto/standalone/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | go_library( 4 | name = "standalone", 5 | srcs = ["unannotated_echo_service.pb.gw.go"], 6 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/standalone", 7 | visibility = ["//examples:__subpackages__"], 8 | deps = [ 9 | "//examples/internal/proto/examplepb", 10 | "//runtime", 11 | "//utilities", 12 | "@org_golang_google_grpc//:grpc", 13 | "@org_golang_google_grpc//codes", 14 | "@org_golang_google_grpc//grpclog", 15 | "@org_golang_google_grpc//metadata", 16 | "@org_golang_google_grpc//status", 17 | "@org_golang_google_protobuf//proto", 18 | ], 19 | ) 20 | 21 | alias( 22 | name = "go_default_library", 23 | actual = ":standalone", 24 | visibility = ["//examples:__subpackages__"], 25 | ) 26 | -------------------------------------------------------------------------------- /examples/internal/proto/sub/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | proto_library( 8 | name = "sub_proto", 9 | srcs = ["message.proto"], 10 | ) 11 | 12 | go_proto_library( 13 | name = "sub_go_proto", 14 | compilers = ["//:go_apiv2"], 15 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/sub", 16 | proto = ":sub_proto", 17 | ) 18 | 19 | go_library( 20 | name = "sub", 21 | embed = [":sub_go_proto"], 22 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/sub", 23 | ) 24 | 25 | alias( 26 | name = "go_default_library", 27 | actual = ":sub", 28 | visibility = ["//examples:__subpackages__"], 29 | ) 30 | -------------------------------------------------------------------------------- /examples/internal/proto/sub/message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package grpc.gateway.examples.internal.proto.sub; 4 | 5 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/sub"; 6 | 7 | message StringMessage { 8 | required string value = 1; 9 | } 10 | -------------------------------------------------------------------------------- /examples/internal/proto/sub/message.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "examples/internal/proto/sub/message.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "@type": { 19 | "type": "string" 20 | } 21 | }, 22 | "additionalProperties": {} 23 | }, 24 | "rpcStatus": { 25 | "type": "object", 26 | "properties": { 27 | "code": { 28 | "type": "integer", 29 | "format": "int32" 30 | }, 31 | "message": { 32 | "type": "string" 33 | }, 34 | "details": { 35 | "type": "array", 36 | "items": { 37 | "type": "object", 38 | "$ref": "#/definitions/protobufAny" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/proto/sub2/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | proto_library( 8 | name = "sub2_proto", 9 | srcs = ["message.proto"], 10 | ) 11 | 12 | go_proto_library( 13 | name = "sub2_go_proto", 14 | compilers = ["//:go_apiv2"], 15 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/sub2", 16 | proto = ":sub2_proto", 17 | ) 18 | 19 | go_library( 20 | name = "sub2", 21 | embed = [":sub2_go_proto"], 22 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/sub2", 23 | ) 24 | 25 | alias( 26 | name = "go_default_library", 27 | actual = ":sub2", 28 | visibility = ["//examples:__subpackages__"], 29 | ) 30 | -------------------------------------------------------------------------------- /examples/internal/proto/sub2/message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.examples.internal.proto.sub2; 4 | 5 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/sub2"; 6 | 7 | message IdMessage { 8 | string uuid = 1; 9 | } 10 | -------------------------------------------------------------------------------- /examples/internal/proto/sub2/message.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "examples/internal/proto/sub2/message.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "@type": { 19 | "type": "string" 20 | } 21 | }, 22 | "additionalProperties": {} 23 | }, 24 | "rpcStatus": { 25 | "type": "object", 26 | "properties": { 27 | "code": { 28 | "type": "integer", 29 | "format": "int32" 30 | }, 31 | "message": { 32 | "type": "string" 33 | }, 34 | "details": { 35 | "type": "array", 36 | "items": { 37 | "type": "object", 38 | "$ref": "#/definitions/protobufAny" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/internal/server/echo.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "context" 5 | 6 | examples "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb" 7 | "google.golang.org/grpc" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/grpclog" 10 | "google.golang.org/grpc/metadata" 11 | "google.golang.org/grpc/status" 12 | ) 13 | 14 | // Implements of EchoServiceServer 15 | 16 | type echoServer struct{} 17 | 18 | func newEchoServer() examples.EchoServiceServer { 19 | return new(echoServer) 20 | } 21 | 22 | func (s *echoServer) Echo(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) { 23 | grpclog.Info(msg) 24 | return msg, nil 25 | } 26 | 27 | func (s *echoServer) EchoBody(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) { 28 | grpclog.Info(msg) 29 | grpc.SendHeader(ctx, metadata.New(map[string]string{ 30 | "foo": "foo1", 31 | "bar": "bar1", 32 | })) 33 | grpc.SetTrailer(ctx, metadata.New(map[string]string{ 34 | "foo": "foo2", 35 | "bar": "bar2", 36 | })) 37 | return msg, nil 38 | } 39 | 40 | func (s *echoServer) EchoDelete(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) { 41 | grpclog.Info(msg) 42 | return msg, nil 43 | } 44 | 45 | func (s *echoServer) EchoPatch(ctx context.Context, msg *examples.DynamicMessageUpdate) (*examples.DynamicMessageUpdate, error) { 46 | grpclog.Info(msg) 47 | return msg, nil 48 | } 49 | 50 | func (s *echoServer) EchoUnauthorized(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) { 51 | grpclog.Info(msg) 52 | return nil, status.Error(codes.Unauthenticated, "unauthorized err") 53 | } 54 | -------------------------------------------------------------------------------- /examples/internal/server/fieldmask_helper.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "strings" 5 | 6 | "google.golang.org/protobuf/proto" 7 | "google.golang.org/protobuf/reflect/protoreflect" 8 | field_mask "google.golang.org/protobuf/types/known/fieldmaskpb" 9 | ) 10 | 11 | func applyFieldMask(patchee, patcher proto.Message, mask *field_mask.FieldMask) { 12 | if mask == nil { 13 | return 14 | } 15 | if patchee.ProtoReflect().Descriptor().FullName() != patcher.ProtoReflect().Descriptor().FullName() { 16 | panic("patchee and patcher must be same type") 17 | } 18 | 19 | for _, path := range mask.GetPaths() { 20 | patcherField, patcherParent := getField(patcher.ProtoReflect(), path) 21 | patcheeField, patcheeParent := getField(patchee.ProtoReflect(), path) 22 | patcheeParent.Set(patcheeField, patcherParent.Get(patcherField)) 23 | } 24 | } 25 | 26 | func getField(msg protoreflect.Message, path string) (field protoreflect.FieldDescriptor, parent protoreflect.Message) { 27 | fields := msg.Descriptor().Fields() 28 | parent = msg 29 | names := strings.Split(path, ".") 30 | for i, name := range names { 31 | field = fields.ByName(protoreflect.Name(name)) 32 | 33 | if i < len(names)-1 { 34 | parent = parent.Get(field).Message() 35 | fields = field.Message().Fields() 36 | } 37 | } 38 | 39 | return field, parent 40 | } 41 | -------------------------------------------------------------------------------- /examples/internal/server/non_standard_names.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "context" 5 | 6 | examples "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb" 7 | "google.golang.org/grpc/grpclog" 8 | ) 9 | 10 | // Implements NonStandardServiceServer 11 | 12 | type nonStandardServer struct{} 13 | 14 | func newNonStandardServer() examples.NonStandardServiceServer { 15 | return new(nonStandardServer) 16 | } 17 | 18 | func (s *nonStandardServer) Update(ctx context.Context, msg *examples.NonStandardUpdateRequest) (*examples.NonStandardMessage, error) { 19 | grpclog.Info(msg) 20 | 21 | newMsg := &examples.NonStandardMessage{ 22 | Thing: &examples.NonStandardMessage_Thing{SubThing: &examples.NonStandardMessage_Thing_SubThing{}}, // The fieldmask_helper doesn't generate nested structs if they are nil 23 | } 24 | applyFieldMask(newMsg, msg.Body, msg.UpdateMask) 25 | 26 | grpclog.Info(newMsg) 27 | return newMsg, nil 28 | } 29 | 30 | func (s *nonStandardServer) UpdateWithJSONNames(ctx context.Context, msg *examples.NonStandardWithJSONNamesUpdateRequest) (*examples.NonStandardMessageWithJSONNames, error) { 31 | grpclog.Info(msg) 32 | 33 | newMsg := &examples.NonStandardMessageWithJSONNames{ 34 | Thing: &examples.NonStandardMessageWithJSONNames_Thing{SubThing: &examples.NonStandardMessageWithJSONNames_Thing_SubThing{}}, // The fieldmask_helper doesn't generate nested structs if they are nil 35 | } 36 | applyFieldMask(newMsg, msg.Body, msg.UpdateMask) 37 | 38 | grpclog.Info(newMsg) 39 | return newMsg, nil 40 | } 41 | -------------------------------------------------------------------------------- /examples/internal/server/unannotatedecho.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "context" 5 | 6 | examples "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb" 7 | "google.golang.org/grpc" 8 | "google.golang.org/grpc/grpclog" 9 | "google.golang.org/grpc/metadata" 10 | ) 11 | 12 | // Implements of UnannotatedEchoServiceServer 13 | 14 | type unannotatedEchoServer struct{} 15 | 16 | func newUnannotatedEchoServer() examples.UnannotatedEchoServiceServer { 17 | return new(unannotatedEchoServer) 18 | } 19 | 20 | func (s *unannotatedEchoServer) Echo(ctx context.Context, msg *examples.UnannotatedSimpleMessage) (*examples.UnannotatedSimpleMessage, error) { 21 | grpclog.Info(msg) 22 | return msg, nil 23 | } 24 | 25 | func (s *unannotatedEchoServer) EchoBody(ctx context.Context, msg *examples.UnannotatedSimpleMessage) (*examples.UnannotatedSimpleMessage, error) { 26 | grpclog.Info(msg) 27 | grpc.SendHeader(ctx, metadata.New(map[string]string{ 28 | "foo": "foo1", 29 | "bar": "bar1", 30 | })) 31 | grpc.SetTrailer(ctx, metadata.New(map[string]string{ 32 | "foo": "foo2", 33 | "bar": "bar2", 34 | })) 35 | return msg, nil 36 | } 37 | 38 | func (s *unannotatedEchoServer) EchoDelete(ctx context.Context, msg *examples.UnannotatedSimpleMessage) (*examples.UnannotatedSimpleMessage, error) { 39 | grpclog.Info(msg) 40 | return msg, nil 41 | } 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/grpc-ecosystem/grpc-gateway/v2 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/antihax/optional v1.0.0 7 | github.com/google/go-cmp v0.7.0 8 | github.com/rogpeppe/fastuuid v1.2.0 9 | golang.org/x/oauth2 v0.30.0 10 | golang.org/x/text v0.25.0 11 | google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a 12 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a 13 | google.golang.org/grpc v1.72.2 14 | google.golang.org/protobuf v1.36.6 15 | gopkg.in/yaml.v3 v3.0.1 16 | ) 17 | 18 | require ( 19 | github.com/kr/pretty v0.3.1 // indirect 20 | golang.org/x/net v0.37.0 // indirect 21 | golang.org/x/sys v0.31.0 // indirect 22 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /internal/casing/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 2 | 3 | go_library( 4 | name = "casing", 5 | srcs = ["camel.go"], 6 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/casing", 7 | visibility = ["//:__subpackages__"], 8 | ) 9 | 10 | alias( 11 | name = "go_default_library", 12 | actual = ":casing", 13 | visibility = ["//:__subpackages__"], 14 | ) 15 | 16 | go_test( 17 | name = "casing_test", 18 | srcs = ["camel_test.go"], 19 | embed = [":casing"], 20 | ) 21 | -------------------------------------------------------------------------------- /internal/casing/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2019 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /internal/casing/README.md: -------------------------------------------------------------------------------- 1 | # Case conversion 2 | 3 | This package contains two functions: 4 | - `Camel` copied from the `github.com/golang/protobuf/protoc-gen-go/generator` package. 5 | - `JSONCamelCase` copied from the `github.com/protocolbuffers/protobuf-go/internal/strs` package. 6 | 7 | Both these modules are licensed by The Go Authors, as reflected in this package's [LICENSE.md]. 8 | -------------------------------------------------------------------------------- /internal/casing/camel_test.go: -------------------------------------------------------------------------------- 1 | package casing 2 | 3 | import "testing" 4 | 5 | func TestCamelIdentifier(t *testing.T) { 6 | casingTests := []struct { 7 | name string 8 | input string 9 | want string 10 | }{ 11 | { 12 | "regular snake case identifier", 13 | "snake_case", 14 | "SnakeCase", 15 | }, 16 | { 17 | "snake case identifier with digit", 18 | "snake_case_0_enum", 19 | "SnakeCase_0Enum", 20 | }, 21 | { 22 | "regular snake case identifier with package", 23 | "pathenum.snake_case", 24 | "pathenum.SnakeCase", 25 | }, 26 | { 27 | "snake case identifier with digit and package", 28 | "pathenum.snake_case_0_enum", 29 | "pathenum.SnakeCase_0Enum", 30 | }, 31 | { 32 | "snake case identifier with digit and multiple dots", 33 | "path.pathenum.snake_case_0_enum", 34 | "path.pathenum.SnakeCase_0Enum", 35 | }, 36 | } 37 | 38 | for _, ct := range casingTests { 39 | t.Run(ct.name, func(t *testing.T) { 40 | got := CamelIdentifier(ct.input) 41 | if ct.want != got { 42 | t.Errorf("want: %s, got: %s", ct.want, got) 43 | } 44 | }) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /internal/codegenerator/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | go_library( 6 | name = "codegenerator", 7 | srcs = [ 8 | "doc.go", 9 | "parse_req.go", 10 | "supported_features.go", 11 | ], 12 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator", 13 | deps = [ 14 | "@org_golang_google_protobuf//compiler/protogen", 15 | "@org_golang_google_protobuf//proto", 16 | "@org_golang_google_protobuf//types/pluginpb", 17 | ], 18 | ) 19 | 20 | go_test( 21 | name = "codegenerator_test", 22 | srcs = ["parse_req_test.go"], 23 | deps = [ 24 | ":codegenerator", 25 | "@com_github_google_go_cmp//cmp", 26 | "@org_golang_google_protobuf//proto", 27 | "@org_golang_google_protobuf//testing/protocmp", 28 | "@org_golang_google_protobuf//types/pluginpb", 29 | ], 30 | ) 31 | 32 | alias( 33 | name = "go_default_library", 34 | actual = ":codegenerator", 35 | visibility = ["//:__subpackages__"], 36 | ) 37 | -------------------------------------------------------------------------------- /internal/codegenerator/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package codegenerator contains reusable functions used by the code generators. 3 | */ 4 | package codegenerator 5 | -------------------------------------------------------------------------------- /internal/codegenerator/parse_req.go: -------------------------------------------------------------------------------- 1 | package codegenerator 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "google.golang.org/protobuf/proto" 8 | "google.golang.org/protobuf/types/pluginpb" 9 | ) 10 | 11 | // ParseRequest parses a code generator request from a proto Message. 12 | func ParseRequest(r io.Reader) (*pluginpb.CodeGeneratorRequest, error) { 13 | input, err := io.ReadAll(r) 14 | if err != nil { 15 | return nil, fmt.Errorf("failed to read code generator request: %w", err) 16 | } 17 | req := new(pluginpb.CodeGeneratorRequest) 18 | if err := proto.Unmarshal(input, req); err != nil { 19 | return nil, fmt.Errorf("failed to unmarshal code generator request: %w", err) 20 | } 21 | return req, nil 22 | } 23 | -------------------------------------------------------------------------------- /internal/codegenerator/parse_req_test.go: -------------------------------------------------------------------------------- 1 | package codegenerator_test 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "io" 7 | "strings" 8 | "testing" 9 | 10 | "github.com/google/go-cmp/cmp" 11 | "github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator" 12 | "google.golang.org/protobuf/proto" 13 | "google.golang.org/protobuf/testing/protocmp" 14 | "google.golang.org/protobuf/types/pluginpb" 15 | ) 16 | 17 | var parseReqTests = []struct { 18 | name string 19 | in io.Reader 20 | out *pluginpb.CodeGeneratorRequest 21 | expectErr bool 22 | }{ 23 | { 24 | "Empty input should produce empty output", 25 | mustGetReader(&pluginpb.CodeGeneratorRequest{}), 26 | &pluginpb.CodeGeneratorRequest{}, 27 | false, 28 | }, 29 | { 30 | "Invalid reader should produce error", 31 | &invalidReader{}, 32 | nil, 33 | true, 34 | }, 35 | { 36 | "Invalid proto message should produce error", 37 | strings.NewReader("{}"), 38 | nil, 39 | true, 40 | }, 41 | } 42 | 43 | func TestParseRequest(t *testing.T) { 44 | for _, tt := range parseReqTests { 45 | t.Run(tt.name, func(t *testing.T) { 46 | out, err := codegenerator.ParseRequest(tt.in) 47 | if tt.expectErr && err == nil { 48 | t.Error("did not error as expected") 49 | } 50 | if diff := cmp.Diff(out, tt.out, protocmp.Transform()); diff != "" { 51 | t.Error(diff) 52 | } 53 | }) 54 | } 55 | } 56 | 57 | func mustGetReader(pb proto.Message) io.Reader { 58 | b, err := proto.Marshal(pb) 59 | if err != nil { 60 | panic(err) 61 | } 62 | return bytes.NewBuffer(b) 63 | } 64 | 65 | type invalidReader struct { 66 | } 67 | 68 | func (*invalidReader) Read(p []byte) (int, error) { 69 | return 0, errors.New("invalid reader") 70 | } 71 | -------------------------------------------------------------------------------- /internal/codegenerator/supported_features.go: -------------------------------------------------------------------------------- 1 | package codegenerator 2 | 3 | import ( 4 | "google.golang.org/protobuf/compiler/protogen" 5 | "google.golang.org/protobuf/types/pluginpb" 6 | ) 7 | 8 | func supportedCodeGeneratorFeatures() uint64 { 9 | // Enable support for optional keyword in proto3. 10 | return uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) 11 | } 12 | 13 | // SetSupportedFeaturesOnPluginGen sets supported proto3 features 14 | // on protogen.Plugin. 15 | func SetSupportedFeaturesOnPluginGen(gen *protogen.Plugin) { 16 | gen.SupportedFeatures = supportedCodeGeneratorFeatures() 17 | } 18 | 19 | // SetSupportedFeaturesOnCodeGeneratorResponse sets supported proto3 features 20 | // on pluginpb.CodeGeneratorResponse. 21 | func SetSupportedFeaturesOnCodeGeneratorResponse(resp *pluginpb.CodeGeneratorResponse) { 22 | sf := supportedCodeGeneratorFeatures() 23 | resp.SupportedFeatures = &sf 24 | } 25 | -------------------------------------------------------------------------------- /internal/descriptor/apiconfig/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | proto_library( 8 | name = "apiconfig_proto", 9 | srcs = [ 10 | "apiconfig.proto", 11 | ], 12 | deps = ["@googleapis//google/api:http_proto"], 13 | ) 14 | 15 | go_proto_library( 16 | name = "apiconfig_go_proto", 17 | compilers = ["//:go_apiv2"], 18 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/apiconfig", 19 | proto = ":apiconfig_proto", 20 | deps = ["@org_golang_google_genproto_googleapis_api//annotations"], 21 | ) 22 | 23 | go_library( 24 | name = "apiconfig", 25 | embed = [":apiconfig_go_proto"], 26 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/apiconfig", 27 | ) 28 | 29 | alias( 30 | name = "go_default_library", 31 | actual = ":apiconfig", 32 | visibility = ["//:__subpackages__"], 33 | ) 34 | -------------------------------------------------------------------------------- /internal/descriptor/apiconfig/apiconfig.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.internal.descriptor.apiconfig; 4 | 5 | import "google/api/http.proto"; 6 | 7 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/apiconfig"; 8 | 9 | // GrpcAPIService represents a stripped down version of google.api.Service . 10 | // Compare to https://github.com/googleapis/googleapis/blob/master/google/api/service.proto 11 | // The original imports 23 other protobuf files we are not interested in. If a significant 12 | // subset (>50%) of these start being reproduced in this file we should swap to using the 13 | // full generated version instead. 14 | // 15 | // For the purposes of the gateway generator we only consider a small subset of all 16 | // available features google supports in their service descriptions. Thanks to backwards 17 | // compatibility guarantees by protobuf it is safe for us to remove the other fields. 18 | message GrpcAPIService { 19 | // Http Rule. 20 | google.api.Http http = 1; 21 | } 22 | -------------------------------------------------------------------------------- /internal/descriptor/apiconfig/apiconfig.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "internal/descriptor/apiconfig/apiconfig.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "@type": { 19 | "type": "string" 20 | } 21 | }, 22 | "additionalProperties": {} 23 | }, 24 | "rpcStatus": { 25 | "type": "object", 26 | "properties": { 27 | "code": { 28 | "type": "integer", 29 | "format": "int32" 30 | }, 31 | "message": { 32 | "type": "string" 33 | }, 34 | "details": { 35 | "type": "array", 36 | "items": { 37 | "type": "object", 38 | "$ref": "#/definitions/protobufAny" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /internal/descriptor/openapiconfig/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | proto_library( 6 | name = "openapiconfig_proto", 7 | srcs = ["openapiconfig.proto"], 8 | visibility = ["//:__subpackages__"], 9 | deps = ["//protoc-gen-openapiv2/options:options_proto"], 10 | ) 11 | 12 | go_proto_library( 13 | name = "openapiconfig_go_proto", 14 | compilers = ["//:go_apiv2"], 15 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig", 16 | proto = ":openapiconfig_proto", 17 | visibility = ["//:__subpackages__"], 18 | deps = ["//protoc-gen-openapiv2/options"], 19 | ) 20 | 21 | go_library( 22 | name = "openapiconfig", 23 | embed = [":openapiconfig_go_proto"], 24 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig", 25 | visibility = ["//:__subpackages__"], 26 | ) 27 | 28 | alias( 29 | name = "go_default_library", 30 | actual = ":openapiconfig", 31 | visibility = ["//:__subpackages__"], 32 | ) 33 | -------------------------------------------------------------------------------- /internal/descriptor/openapiconfig/openapiconfig.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.gateway.internal.descriptor.openapiconfig; 4 | 5 | import "protoc-gen-openapiv2/options/openapiv2.proto"; 6 | 7 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig"; 8 | 9 | // OpenAPIFileOption represents OpenAPI options on a file 10 | message OpenAPIFileOption { 11 | string file = 1; 12 | grpc.gateway.protoc_gen_openapiv2.options.Swagger option = 2; 13 | } 14 | 15 | // OpenAPIMethodOption represents OpenAPI options on a method 16 | message OpenAPIMethodOption { 17 | string method = 1; 18 | grpc.gateway.protoc_gen_openapiv2.options.Operation option = 2; 19 | } 20 | 21 | // OpenAPIMessageOption represents OpenAPI options on a message 22 | message OpenAPIMessageOption { 23 | string message = 1; 24 | grpc.gateway.protoc_gen_openapiv2.options.Schema option = 2; 25 | } 26 | 27 | // OpenAPIServiceOption represents OpenAPI options on a service 28 | message OpenAPIServiceOption { 29 | string service = 1; // ex: Service 30 | grpc.gateway.protoc_gen_openapiv2.options.Tag option = 2; 31 | } 32 | 33 | // OpenAPIFieldOption represents OpenAPI options on a field 34 | message OpenAPIFieldOption { 35 | string field = 1; 36 | grpc.gateway.protoc_gen_openapiv2.options.JSONSchema option = 2; 37 | } 38 | 39 | // OpenAPIOptions represents OpenAPI protobuf options 40 | message OpenAPIOptions { 41 | repeated OpenAPIFileOption file = 1; 42 | repeated OpenAPIMethodOption method = 2; 43 | repeated OpenAPIMessageOption message = 3; 44 | repeated OpenAPIServiceOption service = 4; 45 | repeated OpenAPIFieldOption field = 5; 46 | } 47 | 48 | // OpenAPIConfig represents a set of OpenAPI options 49 | message OpenAPIConfig { 50 | OpenAPIOptions openapi_options = 1; 51 | } 52 | -------------------------------------------------------------------------------- /internal/descriptor/openapiconfig/openapiconfig.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "internal/descriptor/openapiconfig/openapiconfig.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "@type": { 19 | "type": "string" 20 | } 21 | }, 22 | "additionalProperties": {} 23 | }, 24 | "rpcStatus": { 25 | "type": "object", 26 | "properties": { 27 | "code": { 28 | "type": "integer", 29 | "format": "int32" 30 | }, 31 | "message": { 32 | "type": "string" 33 | }, 34 | "details": { 35 | "type": "array", 36 | "items": { 37 | "type": "object", 38 | "$ref": "#/definitions/protobufAny" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /internal/generator/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | go_library( 6 | name = "generator", 7 | srcs = ["generator.go"], 8 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/generator", 9 | deps = ["//internal/descriptor"], 10 | ) 11 | 12 | alias( 13 | name = "go_default_library", 14 | actual = ":generator", 15 | visibility = ["//:__subpackages__"], 16 | ) 17 | -------------------------------------------------------------------------------- /internal/generator/generator.go: -------------------------------------------------------------------------------- 1 | // Package generator provides an abstract interface to code generators. 2 | package generator 3 | 4 | import ( 5 | "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor" 6 | ) 7 | 8 | // Generator is an abstraction of code generators. 9 | type Generator interface { 10 | // Generate generates output files from input .proto files. 11 | Generate(targets []*descriptor.File) ([]*descriptor.ResponseFile, error) 12 | } 13 | -------------------------------------------------------------------------------- /internal/httprule/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | go_library( 6 | name = "httprule", 7 | srcs = [ 8 | "compile.go", 9 | "parse.go", 10 | "types.go", 11 | ], 12 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule", 13 | deps = ["//utilities"], 14 | ) 15 | 16 | go_test( 17 | name = "httprule_test", 18 | size = "small", 19 | srcs = [ 20 | "compile_test.go", 21 | "parse_test.go", 22 | "types_test.go", 23 | ], 24 | embed = [":httprule"], 25 | deps = [ 26 | "//utilities", 27 | "@org_golang_google_grpc//grpclog", 28 | ], 29 | ) 30 | 31 | alias( 32 | name = "go_default_library", 33 | actual = ":httprule", 34 | visibility = ["//:__subpackages__"], 35 | ) 36 | -------------------------------------------------------------------------------- /internal/httprule/fuzz.go: -------------------------------------------------------------------------------- 1 | //go:build gofuzz 2 | // +build gofuzz 3 | 4 | package httprule 5 | 6 | func Fuzz(data []byte) int { 7 | if _, err := Parse(string(data)); err != nil { 8 | return 0 9 | } 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /internal/httprule/types.go: -------------------------------------------------------------------------------- 1 | package httprule 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type template struct { 9 | segments []segment 10 | verb string 11 | template string 12 | } 13 | 14 | type segment interface { 15 | fmt.Stringer 16 | compile() (ops []op) 17 | } 18 | 19 | type wildcard struct{} 20 | 21 | type deepWildcard struct{} 22 | 23 | type literal string 24 | 25 | type variable struct { 26 | path string 27 | segments []segment 28 | } 29 | 30 | func (wildcard) String() string { 31 | return "*" 32 | } 33 | 34 | func (deepWildcard) String() string { 35 | return "**" 36 | } 37 | 38 | func (l literal) String() string { 39 | return string(l) 40 | } 41 | 42 | func (v variable) String() string { 43 | var segs []string 44 | for _, s := range v.segments { 45 | segs = append(segs, s.String()) 46 | } 47 | return fmt.Sprintf("{%s=%s}", v.path, strings.Join(segs, "/")) 48 | } 49 | 50 | func (t template) String() string { 51 | var segs []string 52 | for _, s := range t.segments { 53 | segs = append(segs, s.String()) 54 | } 55 | str := strings.Join(segs, "/") 56 | if t.verb != "" { 57 | str = fmt.Sprintf("%s:%s", str, t.verb) 58 | } 59 | return "/" + str 60 | } 61 | -------------------------------------------------------------------------------- /non_module_deps.bzl: -------------------------------------------------------------------------------- 1 | """Module extension for non-module dependencies.""" 2 | 3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 4 | 5 | def _non_module_deps_impl( 6 | # buildifier: disable=unused-variable 7 | mctx): 8 | # TODO(bazelbuild/buildtools#1204): Remove when available as module. 9 | http_archive( 10 | name = "com_github_bazelbuild_buildtools", 11 | sha256 = "444a9e93e77a45f290a96cc09f42681d3c780cfbf4ac9dbf2939b095daeb6d7d", 12 | strip_prefix = "buildtools-8.2.0", 13 | urls = ["https://github.com/bazelbuild/buildtools/archive/v8.2.0.tar.gz"], 14 | ) 15 | 16 | non_module_deps = module_extension( 17 | implementation = _non_module_deps_impl, 18 | ) 19 | -------------------------------------------------------------------------------- /protoc-gen-grpc-gateway/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") 2 | load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler") 3 | 4 | package(default_visibility = ["//visibility:private"]) 5 | 6 | go_library( 7 | name = "protoc-gen-grpc-gateway_lib", 8 | srcs = ["main.go"], 9 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway", 10 | deps = [ 11 | "//internal/codegenerator", 12 | "//internal/descriptor", 13 | "//protoc-gen-grpc-gateway/internal/gengateway", 14 | "@org_golang_google_grpc//grpclog", 15 | "@org_golang_google_protobuf//compiler/protogen", 16 | ], 17 | ) 18 | 19 | go_binary( 20 | name = "protoc-gen-grpc-gateway", 21 | embed = [":protoc-gen-grpc-gateway_lib"], 22 | visibility = ["//visibility:public"], 23 | ) 24 | 25 | go_proto_compiler( 26 | name = "go_gen_grpc_gateway", 27 | plugin = ":protoc-gen-grpc-gateway", 28 | suffix = ".pb.gw.go", 29 | visibility = ["//visibility:public"], 30 | deps = [ 31 | "//runtime:go_default_library", 32 | "//utilities:go_default_library", 33 | "@org_golang_google_grpc//grpclog:go_default_library", 34 | "@org_golang_google_grpc//metadata:go_default_library", 35 | ], 36 | ) 37 | -------------------------------------------------------------------------------- /protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 2 | 3 | package(default_visibility = ["//protoc-gen-grpc-gateway:__subpackages__"]) 4 | 5 | go_library( 6 | name = "gengateway", 7 | srcs = [ 8 | "doc.go", 9 | "generator.go", 10 | "template.go", 11 | ], 12 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway", 13 | deps = [ 14 | "//internal/casing", 15 | "//internal/descriptor", 16 | "//internal/generator", 17 | "//utilities", 18 | "@org_golang_google_grpc//grpclog", 19 | "@org_golang_google_protobuf//proto", 20 | "@org_golang_google_protobuf//types/pluginpb", 21 | ], 22 | ) 23 | 24 | go_test( 25 | name = "gengateway_test", 26 | size = "small", 27 | srcs = [ 28 | "generator_test.go", 29 | "template_test.go", 30 | ], 31 | embed = [":gengateway"], 32 | deps = [ 33 | "//internal/descriptor", 34 | "//internal/httprule", 35 | "@org_golang_google_protobuf//proto", 36 | "@org_golang_google_protobuf//types/descriptorpb", 37 | ], 38 | ) 39 | 40 | alias( 41 | name = "go_default_library", 42 | actual = ":gengateway", 43 | visibility = ["//protoc-gen-grpc-gateway:__subpackages__"], 44 | ) 45 | -------------------------------------------------------------------------------- /protoc-gen-grpc-gateway/internal/gengateway/doc.go: -------------------------------------------------------------------------------- 1 | // Package gengateway provides a code generator for grpc gateway files. 2 | package gengateway 3 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") 2 | 3 | package(default_visibility = ["//visibility:private"]) 4 | 5 | go_library( 6 | name = "protoc-gen-openapiv2_lib", 7 | srcs = ["main.go"], 8 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2", 9 | deps = [ 10 | "//internal/codegenerator", 11 | "//internal/descriptor", 12 | "//protoc-gen-openapiv2/internal/genopenapi", 13 | "//utilities", 14 | "@org_golang_google_grpc//grpclog", 15 | "@org_golang_google_protobuf//proto", 16 | "@org_golang_google_protobuf//types/pluginpb", 17 | ], 18 | ) 19 | 20 | go_binary( 21 | name = "protoc-gen-openapiv2", 22 | embed = [":protoc-gen-openapiv2_lib"], 23 | visibility = ["//visibility:public"], 24 | ) 25 | 26 | go_test( 27 | name = "protoc-gen-openapiv2_test", 28 | size = "small", 29 | srcs = ["main_test.go"], 30 | embed = [":protoc-gen-openapiv2_lib"], 31 | ) 32 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/cycle_test.go: -------------------------------------------------------------------------------- 1 | package genopenapi 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCycle(t *testing.T) { 8 | for _, tt := range []struct { 9 | max int 10 | attempt int 11 | e bool 12 | }{ 13 | { 14 | max: 3, 15 | attempt: 3, 16 | e: true, 17 | }, 18 | { 19 | max: 5, 20 | attempt: 6, 21 | }, 22 | { 23 | max: 1000, 24 | attempt: 1001, 25 | }, 26 | } { 27 | 28 | c := newCycleChecker(tt.max) 29 | var final bool 30 | for i := 0; i < tt.attempt; i++ { 31 | final = c.Check("a") 32 | if !final { 33 | break 34 | } 35 | } 36 | 37 | if final != tt.e { 38 | t.Errorf("got: %t wanted: %t", final, tt.e) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/doc.go: -------------------------------------------------------------------------------- 1 | // Package genopenapi provides a code generator for OpenAPI v2. 2 | package genopenapi 3 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/format.go: -------------------------------------------------------------------------------- 1 | package genopenapi 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io" 7 | 8 | "gopkg.in/yaml.v3" 9 | ) 10 | 11 | type Format string 12 | 13 | const ( 14 | FormatJSON Format = "json" 15 | FormatYAML Format = "yaml" 16 | ) 17 | 18 | type ContentEncoder interface { 19 | Encode(v interface{}) (err error) 20 | } 21 | 22 | func (f Format) Validate() error { 23 | switch f { 24 | case FormatJSON, FormatYAML: 25 | return nil 26 | default: 27 | return errors.New("unknown format: " + string(f)) 28 | } 29 | } 30 | 31 | func (f Format) NewEncoder(w io.Writer) (ContentEncoder, error) { 32 | switch f { 33 | case FormatYAML: 34 | enc := yaml.NewEncoder(w) 35 | enc.SetIndent(2) 36 | 37 | return enc, nil 38 | case FormatJSON: 39 | enc := json.NewEncoder(w) 40 | enc.SetIndent("", " ") 41 | 42 | return enc, nil 43 | default: 44 | return nil, errors.New("unknown format: " + string(f)) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/helpers.go: -------------------------------------------------------------------------------- 1 | //go:build go1.12 2 | // +build go1.12 3 | 4 | package genopenapi 5 | 6 | import ( 7 | "strings" 8 | 9 | "golang.org/x/text/cases" 10 | "golang.org/x/text/language" 11 | ) 12 | 13 | func fieldName(k string) string { 14 | return strings.ReplaceAll(cases.Title(language.AmericanEnglish).String(k), "-", "_") 15 | } 16 | 17 | // this method will filter the same fields and return the unique one 18 | func getUniqueFields(schemaFieldsRequired []string, fieldsRequired []string) []string { 19 | var unique []string 20 | var index *int 21 | 22 | for j, schemaFieldRequired := range schemaFieldsRequired { 23 | index = nil 24 | for i, fieldRequired := range fieldsRequired { 25 | i := i 26 | if schemaFieldRequired == fieldRequired { 27 | index = &i 28 | break 29 | } 30 | } 31 | if index == nil { 32 | unique = append(unique, schemaFieldsRequired[j]) 33 | } 34 | } 35 | return unique 36 | } 37 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/helpers_go111_old.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.12 2 | // +build !go1.12 3 | 4 | package genopenapi 5 | 6 | import "strings" 7 | 8 | func fieldName(k string) string { 9 | return strings.Replace(strings.Title(k), "-", "_", -1) 10 | } 11 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/template_fuzz_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package genopenapi 5 | 6 | import ( 7 | "regexp" 8 | "testing" 9 | ) 10 | 11 | var replaceInternalCommentsRegex = regexp.MustCompile(`(?s)(\r?\n)?[ \t]*(\(--)((.*?--\))|.*$)?`) 12 | 13 | func FuzzRemoveInternalComments(f *testing.F) { 14 | f.Add("Text\n\n(-- Comment --)\n\nMore Text\n") 15 | f.Add("Text\n\n(-- Multi\nLine\n\nComment --)\n\nMore Text\n") 16 | f.Add("(-- Starting with comment --)\n\nMore Text\n") 17 | f.Add("\n\n(-- Starting with new line and comment --)\n\nMore Text\n") 18 | f.Add("Ending with\n\n(-- Comment --)") 19 | f.Fuzz(func(t *testing.T, s string) { 20 | s1 := removeInternalComments(s) 21 | s2 := replaceInternalCommentsRegex.ReplaceAllString(s, "") 22 | if s1 != s2 { 23 | t.Errorf("Unexpected comment removal difference: our function produced %q but regex produced %q on %q", s1, s2, s) 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/testdata/generator/path_item_object.prototext: -------------------------------------------------------------------------------- 1 | file_to_generate: "your/service/v1/your_service.proto" 2 | proto_file: { 3 | name: "your/service/v1/your_service.proto" 4 | package: "your.service.v1" 5 | message_type: { 6 | name: "StringMessage" 7 | field: { 8 | name: "value" 9 | number: 1 10 | label: LABEL_OPTIONAL 11 | type: TYPE_STRING 12 | json_name: "value" 13 | } 14 | } 15 | service: { 16 | name: "YourService" 17 | method: { 18 | name: "Echo" 19 | input_type: ".your.service.v1.StringMessage" 20 | output_type: ".your.service.v1.StringMessage" 21 | options: { 22 | [google.api.http]: { 23 | post: "/api/echo" 24 | } 25 | } 26 | } 27 | } 28 | options: { 29 | go_package: "github.com/yourorg/yourprotos/gen/go/your/service/v1" 30 | } 31 | syntax: "proto3" 32 | } 33 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/testdata/generator/path_item_object.swagger.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: your/service/v1/your_service.proto 4 | version: version not set 5 | tags: 6 | - name: YourService 7 | consumes: 8 | - application/json 9 | produces: 10 | - application/json 11 | paths: 12 | /api/echo: 13 | post: 14 | operationId: YourService_Echo 15 | responses: 16 | "200": 17 | description: A successful response. 18 | schema: 19 | $ref: '#/definitions/v1StringMessage' 20 | parameters: 21 | - name: value 22 | in: query 23 | required: false 24 | type: string 25 | tags: 26 | - YourService 27 | definitions: 28 | v1StringMessage: 29 | type: object 30 | properties: 31 | value: 32 | type: string 33 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/testdata/generator/x_go_type.prototext: -------------------------------------------------------------------------------- 1 | file_to_generate: "test/service/v1/service.proto" 2 | proto_file: { 3 | name: "test/service/v1/service.proto" 4 | package: "test.service.v1" 5 | message_type: { 6 | name: "TestMessage" 7 | field: { 8 | name: "value" 9 | number: 1 10 | label: LABEL_OPTIONAL 11 | type: TYPE_STRING 12 | json_name: "value" 13 | } 14 | } 15 | service: { 16 | name: "TestService" 17 | method: { 18 | name: "Test" 19 | input_type: ".test.service.v1.TestMessage" 20 | output_type: ".test.service.v1.TestMessage" 21 | options: { 22 | [google.api.http]: { 23 | post: "/v1/test" 24 | body: "*" 25 | } 26 | } 27 | } 28 | } 29 | options: { 30 | go_package: "github.com/grpc-ecosystem/grpc-gateway/v2/test/service/v1;servicev1" 31 | } 32 | } -------------------------------------------------------------------------------- /protoc-gen-openapiv2/internal/genopenapi/testdata/generator/x_go_type.swagger.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: test/service/v1/service.proto 4 | version: version not set 5 | tags: 6 | - name: TestService 7 | consumes: 8 | - application/json 9 | produces: 10 | - application/json 11 | paths: 12 | /v1/test: 13 | post: 14 | operationId: TestService_Test 15 | responses: 16 | "200": 17 | description: A successful response. 18 | schema: 19 | $ref: '#/definitions/v1TestMessage' 20 | parameters: 21 | - name: body 22 | in: body 23 | required: true 24 | schema: 25 | $ref: '#/definitions/v1TestMessage' 26 | tags: 27 | - TestService 28 | definitions: 29 | v1TestMessage: 30 | type: object 31 | properties: 32 | value: 33 | type: string 34 | x-go-type: 35 | import: 36 | package: "github.com/grpc-ecosystem/grpc-gateway/v2/test/service/v1" 37 | type: "TestMessage" -------------------------------------------------------------------------------- /protoc-gen-openapiv2/options/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | filegroup( 8 | name = "options_proto_files", 9 | srcs = [ 10 | "annotations.proto", 11 | "openapiv2.proto", 12 | ], 13 | ) 14 | 15 | go_library( 16 | name = "options", 17 | embed = [":options_go_proto"], 18 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options", 19 | ) 20 | 21 | proto_library( 22 | name = "options_proto", 23 | srcs = [ 24 | "annotations.proto", 25 | "openapiv2.proto", 26 | ], 27 | deps = [ 28 | "@com_google_protobuf//:descriptor_proto", 29 | "@com_google_protobuf//:struct_proto", 30 | ], 31 | ) 32 | 33 | go_proto_library( 34 | name = "options_go_proto", 35 | compilers = ["//:go_apiv2"], 36 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options", 37 | proto = ":options_proto", 38 | ) 39 | 40 | alias( 41 | name = "go_default_library", 42 | actual = ":options", 43 | visibility = ["//visibility:public"], 44 | ) 45 | -------------------------------------------------------------------------------- /protoc-gen-openapiv2/options/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | - remote: buf.build/protocolbuffers/go:v1.36.0 4 | out: . 5 | opt: 6 | - paths=source_relative 7 | - default_api_level=API_HYBRID 8 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "helpers:pinGitHubActionDigests" 5 | ], 6 | "baseBranches": [ 7 | "main" 8 | ], 9 | "postUpdateOptions": [ 10 | "gomodTidy" 11 | ], 12 | "packageRules": [ 13 | { 14 | "updateTypes": [ 15 | "minor", 16 | "patch", 17 | "pin", 18 | "digest" 19 | ], 20 | "automerge": true 21 | }, 22 | { 23 | "baseBranchList": [ 24 | "main" 25 | ], 26 | "packageNames": [ 27 | "github.com/golang/protobuf", 28 | "google.golang.org/protobuf" 29 | ], 30 | "groupName": "golang/protobuf" 31 | }, 32 | { 33 | "packagePatterns": [ 34 | "jekyll.*", 35 | "github-pages" 36 | ], 37 | "enabled": false 38 | }, 39 | { 40 | "matchManagers": [ 41 | "github-actions" 42 | ], 43 | "matchPackageNames": [ 44 | "slsa-framework/slsa-github-generator" 45 | ], 46 | "pinDigests": false 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /runtime/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package runtime contains runtime helper functions used by 3 | servers which protoc-gen-grpc-gateway generates. 4 | */ 5 | package runtime 6 | -------------------------------------------------------------------------------- /runtime/internal/examplepb/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library") 2 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | 5 | # gazelle:exclude non_standard_names_grpc.pb.go 6 | 7 | package(default_visibility = ["//visibility:public"]) 8 | 9 | proto_library( 10 | name = "examplepb_proto", 11 | srcs = [ 12 | "example.proto", 13 | "non_standard_names.proto", 14 | "proto2.proto", 15 | "proto3.proto", 16 | ], 17 | deps = [ 18 | "@com_google_protobuf//:any_proto", 19 | "@com_google_protobuf//:duration_proto", 20 | "@com_google_protobuf//:empty_proto", 21 | "@com_google_protobuf//:field_mask_proto", 22 | "@com_google_protobuf//:struct_proto", 23 | "@com_google_protobuf//:timestamp_proto", 24 | "@com_google_protobuf//:wrappers_proto", 25 | "@googleapis//google/api:annotations_proto", 26 | ], 27 | ) 28 | 29 | go_proto_library( 30 | name = "examplepb_go_proto", 31 | compilers = [ 32 | "//:go_apiv2", 33 | "//:go_grpc", 34 | ], 35 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/runtime/internal/examplepb", 36 | proto = ":examplepb_proto", 37 | deps = [ 38 | "@org_golang_google_genproto_googleapis_api//annotations", 39 | ], 40 | ) 41 | 42 | go_library( 43 | name = "examplepb", 44 | embed = [":examplepb_go_proto"], 45 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/runtime/internal/examplepb", 46 | ) 47 | 48 | alias( 49 | name = "go_default_library", 50 | actual = ":examplepb", 51 | visibility = ["//runtime:__subpackages__"], 52 | ) 53 | -------------------------------------------------------------------------------- /runtime/internal/examplepb/proto2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package grpc.gateway.runtime.internal.examplepb; 4 | 5 | option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/runtime/internal/examplepb"; 6 | 7 | message Proto2Message { 8 | optional float float_value = 42; 9 | optional double double_value = 43; 10 | optional int64 int64_value = 3; 11 | optional int32 int32_value = 4; 12 | optional uint64 uint64_value = 5; 13 | optional uint32 uint32_value = 6; 14 | optional bool bool_value = 7; 15 | optional string string_value = 8; 16 | optional bytes bytes_value = 9; 17 | repeated string repeated_value = 10; 18 | } 19 | -------------------------------------------------------------------------------- /runtime/marshal_httpbodyproto.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | "google.golang.org/genproto/googleapis/api/httpbody" 5 | ) 6 | 7 | // HTTPBodyMarshaler is a Marshaler which supports marshaling of a 8 | // google.api.HttpBody message as the full response body if it is 9 | // the actual message used as the response. If not, then this will 10 | // simply fallback to the Marshaler specified as its default Marshaler. 11 | type HTTPBodyMarshaler struct { 12 | Marshaler 13 | } 14 | 15 | // ContentType returns its specified content type in case v is a 16 | // google.api.HttpBody message, otherwise it will fall back to the default Marshalers 17 | // content type. 18 | func (h *HTTPBodyMarshaler) ContentType(v interface{}) string { 19 | if httpBody, ok := v.(*httpbody.HttpBody); ok { 20 | return httpBody.GetContentType() 21 | } 22 | return h.Marshaler.ContentType(v) 23 | } 24 | 25 | // Marshal marshals "v" by returning the body bytes if v is a 26 | // google.api.HttpBody message, otherwise it falls back to the default Marshaler. 27 | func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) { 28 | if httpBody, ok := v.(*httpbody.HttpBody); ok { 29 | return httpBody.GetData(), nil 30 | } 31 | return h.Marshaler.Marshal(v) 32 | } 33 | -------------------------------------------------------------------------------- /runtime/marshal_httpbodyproto_test.go: -------------------------------------------------------------------------------- 1 | package runtime_test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 8 | "google.golang.org/genproto/googleapis/api/httpbody" 9 | "google.golang.org/protobuf/encoding/protojson" 10 | ) 11 | 12 | func TestHTTPBodyContentType(t *testing.T) { 13 | m := runtime.HTTPBodyMarshaler{ 14 | &runtime.JSONPb{ 15 | MarshalOptions: protojson.MarshalOptions{ 16 | UseProtoNames: true, 17 | }, 18 | }, 19 | } 20 | expected := "CustomContentType" 21 | message := &httpbody.HttpBody{ 22 | ContentType: expected, 23 | } 24 | res := m.ContentType(nil) 25 | if res != "application/json" { 26 | t.Errorf("content type not equal (%q, %q)", res, expected) 27 | } 28 | res = m.ContentType(message) 29 | if res != expected { 30 | t.Errorf("content type not equal (%q, %q)", res, expected) 31 | } 32 | } 33 | 34 | func TestHTTPBodyMarshal(t *testing.T) { 35 | m := runtime.HTTPBodyMarshaler{ 36 | &runtime.JSONPb{ 37 | MarshalOptions: protojson.MarshalOptions{ 38 | UseProtoNames: true, 39 | }, 40 | }, 41 | } 42 | expected := []byte("Some test") 43 | message := &httpbody.HttpBody{ 44 | Data: expected, 45 | } 46 | res, err := m.Marshal(message) 47 | if err != nil { 48 | t.Errorf("m.Marshal(%#v) failed with %v; want success", message, err) 49 | } 50 | if !bytes.Equal(res, expected) { 51 | t.Errorf("Marshalled data not equal (%q, %q)", res, expected) 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /runtime/marshal_json.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | ) 7 | 8 | // JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON 9 | // with the standard "encoding/json" package of Golang. 10 | // Although it is generally faster for simple proto messages than JSONPb, 11 | // it does not support advanced features of protobuf, e.g. map, oneof, .... 12 | // 13 | // The NewEncoder and NewDecoder types return *json.Encoder and 14 | // *json.Decoder respectively. 15 | type JSONBuiltin struct{} 16 | 17 | // ContentType always Returns "application/json". 18 | func (*JSONBuiltin) ContentType(_ interface{}) string { 19 | return "application/json" 20 | } 21 | 22 | // Marshal marshals "v" into JSON 23 | func (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) { 24 | return json.Marshal(v) 25 | } 26 | 27 | // MarshalIndent is like Marshal but applies Indent to format the output 28 | func (j *JSONBuiltin) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { 29 | return json.MarshalIndent(v, prefix, indent) 30 | } 31 | 32 | // Unmarshal unmarshals JSON data into "v". 33 | func (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error { 34 | return json.Unmarshal(data, v) 35 | } 36 | 37 | // NewDecoder returns a Decoder which reads JSON stream from "r". 38 | func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder { 39 | return json.NewDecoder(r) 40 | } 41 | 42 | // NewEncoder returns an Encoder which writes JSON stream into "w". 43 | func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder { 44 | return json.NewEncoder(w) 45 | } 46 | 47 | // Delimiter for newline encoded JSON streams. 48 | func (j *JSONBuiltin) Delimiter() []byte { 49 | return []byte("\n") 50 | } 51 | -------------------------------------------------------------------------------- /runtime/marshal_proto.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | 7 | "google.golang.org/protobuf/proto" 8 | ) 9 | 10 | // ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes 11 | type ProtoMarshaller struct{} 12 | 13 | // ContentType always returns "application/octet-stream". 14 | func (*ProtoMarshaller) ContentType(_ interface{}) string { 15 | return "application/octet-stream" 16 | } 17 | 18 | // Marshal marshals "value" into Proto 19 | func (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) { 20 | message, ok := value.(proto.Message) 21 | if !ok { 22 | return nil, errors.New("unable to marshal non proto field") 23 | } 24 | return proto.Marshal(message) 25 | } 26 | 27 | // Unmarshal unmarshals proto "data" into "value" 28 | func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error { 29 | message, ok := value.(proto.Message) 30 | if !ok { 31 | return errors.New("unable to unmarshal non proto field") 32 | } 33 | return proto.Unmarshal(data, message) 34 | } 35 | 36 | // NewDecoder returns a Decoder which reads proto stream from "reader". 37 | func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder { 38 | return DecoderFunc(func(value interface{}) error { 39 | buffer, err := io.ReadAll(reader) 40 | if err != nil { 41 | return err 42 | } 43 | return marshaller.Unmarshal(buffer, value) 44 | }) 45 | } 46 | 47 | // NewEncoder returns an Encoder which writes proto stream into "writer". 48 | func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder { 49 | return EncoderFunc(func(value interface{}) error { 50 | buffer, err := marshaller.Marshal(value) 51 | if err != nil { 52 | return err 53 | } 54 | if _, err := writer.Write(buffer); err != nil { 55 | return err 56 | } 57 | 58 | return nil 59 | }) 60 | } 61 | -------------------------------------------------------------------------------- /runtime/mux_internal_test.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | "sort" 5 | "testing" 6 | ) 7 | 8 | func TestWithIncomingHeaderMatcher_matchedMalformedHeaders(t *testing.T) { 9 | tests := []struct { 10 | name string 11 | matcher HeaderMatcherFunc 12 | want []string 13 | }{ 14 | { 15 | "nil matcher returns nothing", 16 | nil, 17 | nil, 18 | }, 19 | { 20 | "default matcher returns nothing", 21 | DefaultHeaderMatcher, 22 | nil, 23 | }, 24 | { 25 | "passthrough matcher returns all malformed headers", 26 | func(s string) (string, bool) { 27 | return s, true 28 | }, 29 | []string{"connection"}, 30 | }, 31 | } 32 | 33 | sliceEqual := func(a, b []string) bool { 34 | if len(a) != len(b) { 35 | return false 36 | } 37 | sort.Slice(a, func(i, j int) bool { 38 | return a[i] < a[j] 39 | }) 40 | sort.Slice(b, func(i, j int) bool { 41 | return a[i] < a[j] 42 | }) 43 | for idx := range a { 44 | if a[idx] != b[idx] { 45 | return false 46 | } 47 | } 48 | return true 49 | } 50 | 51 | for _, tt := range tests { 52 | out := tt.matcher.matchedMalformedHeaders() 53 | if !sliceEqual(tt.want, out) { 54 | t.Errorf("matchedMalformedHeaders not match; Want %v; got %v", 55 | tt.want, out) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /utilities/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | go_library( 6 | name = "utilities", 7 | srcs = [ 8 | "doc.go", 9 | "pattern.go", 10 | "readerfactory.go", 11 | "string_array_flag.go", 12 | "trie.go", 13 | ], 14 | importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", 15 | ) 16 | 17 | go_test( 18 | name = "utilities_test", 19 | size = "small", 20 | srcs = [ 21 | "string_array_flag_test.go", 22 | "trie_test.go", 23 | ], 24 | deps = [":utilities"], 25 | ) 26 | 27 | alias( 28 | name = "go_default_library", 29 | actual = ":utilities", 30 | visibility = ["//visibility:public"], 31 | ) 32 | -------------------------------------------------------------------------------- /utilities/doc.go: -------------------------------------------------------------------------------- 1 | // Package utilities provides members for internal use in grpc-gateway. 2 | package utilities 3 | -------------------------------------------------------------------------------- /utilities/pattern.go: -------------------------------------------------------------------------------- 1 | package utilities 2 | 3 | // OpCode is an opcode of compiled path patterns. 4 | type OpCode int 5 | 6 | // These constants are the valid values of OpCode. 7 | const ( 8 | // OpNop does nothing 9 | OpNop = OpCode(iota) 10 | // OpPush pushes a component to stack 11 | OpPush 12 | // OpLitPush pushes a component to stack if it matches to the literal 13 | OpLitPush 14 | // OpPushM concatenates the remaining components and pushes it to stack 15 | OpPushM 16 | // OpConcatN pops N items from stack, concatenates them and pushes it back to stack 17 | OpConcatN 18 | // OpCapture pops an item and binds it to the variable 19 | OpCapture 20 | // OpEnd is the least positive invalid opcode. 21 | OpEnd 22 | ) 23 | -------------------------------------------------------------------------------- /utilities/readerfactory.go: -------------------------------------------------------------------------------- 1 | package utilities 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | ) 7 | 8 | // IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins 9 | // at the start of the stream 10 | func IOReaderFactory(r io.Reader) (func() io.Reader, error) { 11 | b, err := io.ReadAll(r) 12 | if err != nil { 13 | return nil, err 14 | } 15 | 16 | return func() io.Reader { 17 | return bytes.NewReader(b) 18 | }, nil 19 | } 20 | -------------------------------------------------------------------------------- /utilities/string_array_flag.go: -------------------------------------------------------------------------------- 1 | package utilities 2 | 3 | import ( 4 | "flag" 5 | "strings" 6 | ) 7 | 8 | // flagInterface is a cut down interface to `flag` 9 | type flagInterface interface { 10 | Var(value flag.Value, name string, usage string) 11 | } 12 | 13 | // StringArrayFlag defines a flag with the specified name and usage string. 14 | // The return value is the address of a `StringArrayFlags` variable that stores the repeated values of the flag. 15 | func StringArrayFlag(f flagInterface, name string, usage string) *StringArrayFlags { 16 | value := &StringArrayFlags{} 17 | f.Var(value, name, usage) 18 | return value 19 | } 20 | 21 | // StringArrayFlags is a wrapper of `[]string` to provider an interface for `flag.Var` 22 | type StringArrayFlags []string 23 | 24 | // String returns a string representation of `StringArrayFlags` 25 | func (i *StringArrayFlags) String() string { 26 | return strings.Join(*i, ",") 27 | } 28 | 29 | // Set appends a value to `StringArrayFlags` 30 | func (i *StringArrayFlags) Set(value string) error { 31 | *i = append(*i, value) 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /utilities/string_array_flag_test.go: -------------------------------------------------------------------------------- 1 | package utilities_test 2 | 3 | import ( 4 | "flag" 5 | "reflect" 6 | "testing" 7 | 8 | "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" 9 | ) 10 | 11 | func TestStringArrayFlag(t *testing.T) { 12 | tests := []struct { 13 | name string 14 | flags []string 15 | want string 16 | }{ 17 | { 18 | name: "No Value", 19 | flags: []string{}, 20 | want: "", 21 | }, 22 | { 23 | name: "Single Value", 24 | flags: []string{"--my_flag=1"}, 25 | want: "1", 26 | }, 27 | { 28 | name: "Repeated Value", 29 | flags: []string{"--my_flag=1", "--my_flag=2"}, 30 | want: "1,2", 31 | }, 32 | { 33 | name: "Repeated Same Value", 34 | flags: []string{"--my_flag=1", "--my_flag=1"}, 35 | want: "1,1", 36 | }, 37 | } 38 | for _, tt := range tests { 39 | t.Run(tt.name, func(t *testing.T) { 40 | flagSet := flag.NewFlagSet("test", flag.PanicOnError) 41 | result := utilities.StringArrayFlag(flagSet, "my_flag", "repeated flag") 42 | if err := flagSet.Parse(tt.flags); err != nil { 43 | t.Errorf("flagSet.Parse() failed with %v", err) 44 | } 45 | if !reflect.DeepEqual(result.String(), tt.want) { 46 | t.Errorf("StringArrayFlag() = %v, want %v", result.String(), tt.want) 47 | } 48 | }) 49 | } 50 | } 51 | --------------------------------------------------------------------------------