{"id":13525256,"url":"https://github.com/thangchung/GrpcJsonTranscoder","last_synced_at":"2025-04-01T04:31:38.013Z","repository":{"id":35057167,"uuid":"200482954","full_name":"thangchung/GrpcJsonTranscoder","owner":"thangchung","description":"A filter which allows a RESTful JSON API client to send requests to .NET web server over HTTP and get proxied to a gRPC service","archived":false,"fork":false,"pushed_at":"2024-02-04T20:16:03.000Z","size":9617,"stargazers_count":118,"open_issues_count":6,"forks_count":26,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T05:07:11.732Z","etag":null,"topics":["api-gateway","cloud-native","dotnet","dotnet-core","grpc","microservices","microservices-architecture","ocelot","rest-api","restful-api"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thangchung.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-04T11:13:13.000Z","updated_at":"2024-12-14T15:35:47.000Z","dependencies_parsed_at":"2024-10-23T03:30:39.612Z","dependency_job_id":null,"html_url":"https://github.com/thangchung/GrpcJsonTranscoder","commit_stats":{"total_commits":30,"total_committers":2,"mean_commits":15.0,"dds":"0.19999999999999996","last_synced_commit":"8aa92225c8579133c3e0c8c699e97705216bb178"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangchung%2FGrpcJsonTranscoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangchung%2FGrpcJsonTranscoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangchung%2FGrpcJsonTranscoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangchung%2FGrpcJsonTranscoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thangchung","download_url":"https://codeload.github.com/thangchung/GrpcJsonTranscoder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246418644,"owners_count":20773938,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-gateway","cloud-native","dotnet","dotnet-core","grpc","microservices","microservices-architecture","ocelot","rest-api","restful-api"],"created_at":"2024-08-01T06:01:17.181Z","updated_at":"2025-04-01T04:31:37.978Z","avatar_url":"https://github.com/thangchung.png","language":"C#","funding_links":[],"categories":["ContribProject","C\\#"],"sub_categories":[],"readme":"# Grpc-Json Transcoder project\n\n[![Price](https://img.shields.io/badge/price-FREE-0098f7.svg)](https://github.com/thangchung/GrpcJsonTranscoder/blob/master/LICENSE)\n[![version](https://img.shields.io/nuget/v/GrpcJsonTranscoder.svg?label=version)](https://www.nuget.org/packages?q=GrpcJsonTranscoder)\n\nThis is a filter that allows a RESTful JSON API client (Ocelot Gateway) to send requests to .NET Web API (Aggregator Service) over HTTP and get proxied to a gRPC service (on the downstream).\n\nThis project is inspired by [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) which is totally for golang, [grpc-dynamic-gateway](https://github.com/konsumer/grpc-dynamic-gateway) is for nodejs. And especially, [Envoy gRPC-JSON transcoder](https://www.envoyproxy.io/docs/envoy/latest/configuration/http_filters/grpc_json_transcoder_filter) is the best of transcoding in this area, but it is only on the infrastructure level. You also can use it just like my project used at [coolstore-microservices](https://github.com/vietnam-devs/coolstore-microservices/blob/master/deploys/dockers/envoy-proxy/envoy.yaml). We might use the approach from Microsoft at [GrpcHttpApi](https://github.com/aspnet/AspLabs/blob/master/src/GrpcHttpApi/README.md), but it is not publish in the official release by Microsoft in the meantime.\n\ngRPC parser borrows the idea from [Ocelot.GrpcHttpGateway](https://github.com/BuiltCloud/Ocelot.GrpcHttpGateway) code-based.\n\n## Give a Star!\n\nIf you liked [`GrpcJsonTranscoder`](https://github.com/thangchung/GrpcJsonTranscoder) project or if it helped you, please give a star :star: for this repository. That will not only help strengthen our .NET community but also improve cloud-native apps development skills for .NET developers in around the world. Thank you very much :+1:\n\nCheck out my [blog](https://medium.com/@thangchung) or say hi on [Twitter](https://twitter.com/thangchung)!\n\n## How to run it!\n\n![](assets/GrpcJsonTranscoder.gif)\n\n\n```bash\n$ docker-compose up\n```\n\nor \n\n```bash\n$ bash\n$ start.sh # I haven't done it yet :p\n```\n\n\u003e In the mean time, we open up the visual studio, run multiple projects included OcelotGateway, AggregationRestApi, ProductCatalogGrpcServer and GreatGrpcServer\n\n- OcelotGateway (.NET Core 3.1): \n  - REST: http://localhost:5000\n- WeatherServer (.NET Core 3.1): \n  - REST: http://localhost:5001\n- ProductCatalogGrpcServer (.NET Core 3.1): \n  - REST: http://localhost:5002\n  - gRPC: http://localhost:50022\n- GreatGrpcServer (.NET Core 3.1): \n  - gRPC: http://localhost:5003\n\nTest it as below:\n\n```bash\n# gRPC\n$ curl -X GET -H 'content-type: application/grpc' -k http://localhost:5000/say/Bob\n$ {\"Message\":\"Hello Bob\"}\n```\n\n```bash\n# gRPC\n$ curl -X GET -H 'content-type: application/grpc' -k http://localhost:5000/products\n$ {\"Products\":[{\"Id\":1,\"Name\":\"product 1\",\"Quantity\":52,\"Description\":\"description of product 1\"},...]}\n```\n\n```bash\n# gRPC\n$ curl -X POST -H 'content-type: application/grpc' -d '{ \"name\": \"product 1\", \"quantity\": 1, \"description\": \"this is product 1\" }' -k http://localhost:5000/products\n$ {\"Product\":{\"Id\":915,\"Name\":\"product 1 created\",\"Quantity\":1,\"Description\":\"this is product 1 created\"}}\n```\n\n```bash\n# REST Api\n$ curl -X GET -H 'content-type: application/json' -k http://localhost:5000/weather \n$ [{\"date\":\"2019-08-17T18:34:41.1090164+07:00\",\"temperatureC\":-6,\"temperatureF\":22,\"summary\":\"Sweltering\"},{\"date\":\"2019-08-18T18:34:41.1090371+07:00\",\"temperatureC\":27,\"temperatureF\":80,\"summary\":\"Hot\"},{\"date\":\"2019-08-19T18:34:41.1090499+07:00\",\"temperatureC\":33,\"temperatureF\":91,\"summary\":\"Balmy\"},{\"date\":\"2019-08-20T18:34:41.1090617+07:00\",\"temperatureC\":-14,\"temperatureF\":7,\"summary\":\"Chilly\"},{\"date\":\"2019-08-21T18:34:41.1090743+07:00\",\"temperatureC\":22,\"temperatureF\":71,\"summary\":\"Hot\"}]\n```\n\n**Notes**:\n- REST method: `content-type: application/json` is for REST method on the downstream services.\n- gRPC method: `content-type: application/grpc` is really important if you call to `gRPC endpoint` on the downstream services.\n\n## How to understand it!\n\nThe project aims to .NET community and its ecosystem which leverage the power of [Ocelot Gateway](https://github.com/ThreeMammals/Ocelot) which is very powerful in the gateway components were used by various of companies and sample source code when we try to adopt the microservices architecture project.\n\n![](assets/overview_option1.png)\n\nThat's quite simple with only a few steps to make it work :)\nCreate the .NET Core project with Ocelot in place, then put the configuration as below\n\n```json\n{\n  \"ReRoutes\": [\n    {\n      \"UpstreamPathTemplate\": \"/say/{name}\",\n      \"UpstreamHttpMethod\": [ \"Get\" ],\n      \"DownstreamPathTemplate\": \"/Greet.Greeter/SayHello\",\n      \"DownstreamScheme\": \"http\",\n      \"DownstreamHostAndPorts\": [\n        {\n          \"Host\": \"127.0.0.1\",\n          \"Port\": 5003\n        }\n      ]\n    },\n    {\n      \"UpstreamPathTemplate\": \"/products\",\n      \"UpstreamHttpMethod\": [ \"Get\" ],\n      \"DownstreamPathTemplate\": \"/ProductCatalog.Product/GetProducts\",\n      \"DownstreamScheme\": \"http\",\n      \"DownstreamHostAndPorts\": [\n        {\n          \"Host\": \"127.0.0.1\",\n          \"Port\": 5002\n        }\n      ]\n    },\n    {\n      \"UpstreamPathTemplate\": \"/products\",\n      \"UpstreamHttpMethod\": [ \"Post\" ],\n      \"DownstreamPathTemplate\": \"/ProductCatalog.Product/CreateProduct\",\n      \"DownstreamScheme\": \"http\",\n      \"DownstreamHostAndPorts\": [\n        {\n          \"Host\": \"127.0.0.1\",\n          \"Port\": 5002\n        }\n      ]\n    },\n    {\n      \"UpstreamPathTemplate\": \"/weather\",\n      \"UpstreamHttpMethod\": [ \"Get\" ],\n      \"DownstreamPathTemplate\": \"/weatherforecast\",\n      \"DownstreamScheme\": \"http\",\n      \"DownstreamHostAndPorts\": [\n        {\n          \"Host\": \"localhost\",\n          \"Port\": 5001\n        }\n      ]\n    }\n  ],\n  \"GlobalConfiguration\": {\n  }\n}\n```\n\nThen in code `Program.cs`, you only put a few line\n\n```csharp\nvar configuration = new OcelotPipelineConfiguration\n{\n    PreQueryStringBuilderMiddleware = async (ctx, next) =\u003e\n    {\n        await ctx.HandleGrpcRequestAsync(next);\n    }\n};\n\napp.UseOcelot(configuration).Wait();\n```\n\n### **Don't believe what I said. Try it!**\n\n\u003e We haven't tested it with stream and full-duplex transport protocols yet. So we feel free to contribute by the .NET community.\n\n## Contributing\n\n1. Fork it!\n2. Create your feature branch: `git checkout -b my-new-feature`\n3. Commit your changes: `git commit -am 'Add some feature'`\n4. Push to the branch: `git push origin my-new-feature`\n5. Submit a pull request :p","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthangchung%2FGrpcJsonTranscoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthangchung%2FGrpcJsonTranscoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthangchung%2FGrpcJsonTranscoder/lists"}