This is grpc, Google's remote procedure call framework based on protobuffers. You don't really use it to expose public services, you mostly use it when you control both client and server endpoints, such as microservices.
You get type marshalling and other niceties with it that you don't get with REST, and it is much lighter and less complex than SOAP (on which WCF is based). Another decent alternative is json-rpc. Cross-platfofm compatibility is also miles better (ws-security and soap exceptions anybody?)
> You don't really use it to expose public services
Why not? Google Cloud certainly does. Google Ads also exposes gRPC API. Google Assistant SDK is basically gRPC too. You get efficient typed client libraries in 10 or more languages for free. No reason not to consider it for public-facing endpoints.
"When a message is parsed, if it does not contain an optional element, the corresponding field in the parsed object is set to the default value for that field. The default value can be specified as part of the message description. For example, let's say you want to provide a default value of 10 for a SearchRequest's result_per_page value.
If the default value is not specified for an optional element, a type-specific default value is used instead: for strings, the default value is the empty string. For bytes, the default value is the empty byte string. For bools, the default value is false. For numeric types, the default value is zero. For enums, the default value is the first value listed in the enum's type definition. This means care must be taken when adding a value to the beginning of an enum value list. See the Updating A Message Type section for guidelines on how to safely change definitions."
Well according to the docs on protocol buffers at least my understanding is as I have read elsewhere.
My favorite other nicety is forward and backwards compatibility. Having an older binary being able to easily handle the next version of the incoming proto, and also to not loose any of the not-yet-understood fields.
I highly recommend using it for public endpoints too. It's much nicer than worrying about a supported up-to-date client library in your language or using yet another variation of JSON/HTTP/REST that's unique to every API.
Some databases and queues are starting to use this now and it makes it incredibly easy to get started since we can generate our own clients and integrate at whatever level we need.
I'm starting to steer our dev team towards this as well, would you have any good links to the gotchas involved in using grpc for public endpoints (if coming from REST as a legacy base)? e.g. for authentication and authorization, throttling etc? I looked at kong, but it seems the plugins don't apply to grpc.
Short answer is yes for most workloads. It's fast, scalable and well supported.
WCF could operate over pipes which was cool for machine local IPC, but beyond that I think gRPC is superior.
But I asked your exact question to the dotnet team and architect David Fowler gave me a decent answer.
> "I don't know that we have a definitive answer as yet and the GRPC experience while great isn't nearly as smooth (as of writing) as the WCF experience. I would say that it's definitely going to be one of the main RPC option of choice going forward but it;s a bit early to say that this is THE blessed new way."
I liked kinda liked it, but trying to unify HTTP, TCP, Pipes and MSMQ into a single framework was probably overly ambitious. WCF always felt very complicated with all sorts of sharp edges to me.
WCF also originally supported peer-to-peer network topologies, discovery methods like PNRP (Microsoft's competitor standard to eventual "winner" Bonjour/mDNS), various versions of the SOAP metadata formats, and WS-* standards, etc.
It was definitely ambitious. When it worked it was sometimes magic, and when it didn't it was a giant mess to resolve.
[ETA: In one past life I made the mistake of trying to use WCF Peer-to-Peer for a project and I still have scars from that. :O]
I liked WCF, but .net devs insisting on using it to create pointless separate physical layers for web apps dulled my enthusiasm. Resume driven development in it's highest form.
This is always their answer - whether it's about .NET vs .NET Core, Winforms vs WPF, ADO.NET vs EF, Webforms vs MVC, or even language features like "var" (remember that originally they would tell you to avoid 'var' unless you're dealing with Linq).
"The new thing isn't immediately going to replace the old thing going forward" and then it does.
(And it should. I just don't get why they're always tiptoeing around that same point.)
This is great for people heavily invested in the .NET world. I like the integration with VS, and with the language overall.
We worked with a small vendor on a project at work last year, where he was building a frontend for our gRPC based backend system. My team inherited him from another division that was winding down, and though he had weird choices of tooling and frameworks, we couldn't dictate what he used as that was out of our control.
What we imposed though was that he only use gRPC to communicate with our services. He struggled a lot, I spent about an hour with him trying to compile the proto files. He also weirdly converted every message to JSON then XML. I assumed he'd been used to covering from JSON to XML. In the end, we had a poor experience and decided to rebuild the thing in-house.
My observations were that other than unfamiliarity with gRPC, he knows his way around MS stuff, the lack of seamless integration with his technology stack.
This integration should make it easier for people to get productive faster, and for new users to experiment.
I wonder if that is a mistake. All other pages have a decent text size and for some reason when you click in on individual blog pages they are set with a font-size of 0.6 rem.
If you're doing networking, there is very useful new stuff in the latest version of C# and .NET,. but it's Spans and Pipelines more than default interfaces.
Async is not new at all, but classes that really leverage it well might be (pipelines again).
Is async streams and "await foreach" just syntactic sugar for things that could still be done beforehand, albeit with more code?
I mean, "slightly more code" - you can say the same about "async ... await" in general, but then it's "insanely more code" and huge potential for error.
nope async streams weren't really possible before without an unnecessary allocation.
i.e. a List<Task<T>> is not the same as an AsyncEnumerable<T>. List<Func<Task<T>>> would be more equivalent, but you needed to have a List<T> which you need to fill beforehand.
Not quite. F# and a few other languages have had this capability for a few years now. Its effectively making the MoveNext() function on the enumerator object an async operation instead of a blocking one. This allows a foreach loop for example to wait until the next object comes without tying up the thread. Useful for things like pulling off a remote message queue, messages off a network, etc where the waiting for the next item in your "foreach" loop involves async/task based operations and you don't want to block the current thread.
I expect that it uses Pipelines ( * ) which is a new high-performance design using Span<T> and related classes inside, and these are new, are not in netstandard2.0.
Moving data onto and off the network efficiently is (one of) the things that Span<T> was created for.
gRPC client requires HTTP/2, and HttpClient (the .NET library for making HTTP requests) didn't previously support HTTP/2. The gRPC client actually supports netstandard2.1. Any .NET implementation that supports HTTP/2 should support running the gRPC client.
Kestrel (the .NET web server) already supported HTTP/2 but it required some new features in .NET 3.0 to fully support hosting gRPC services.
Also the code generated goes to obj directory so it's not versioned. I think this is nice way to do code generation, and sidesteps some of the need for type providers in the future for C#.
Very glad French culture is infusing GAFAM (manger means to eat). More seriously, typos like that in the first sentence of a post denotes a serious lack of attention to details.
45 comments
[ 2.1 ms ] story [ 166 ms ] threadYou get type marshalling and other niceties with it that you don't get with REST, and it is much lighter and less complex than SOAP (on which WCF is based). Another decent alternative is json-rpc. Cross-platfofm compatibility is also miles better (ws-security and soap exceptions anybody?)
Why not? Google Cloud certainly does. Google Ads also exposes gRPC API. Google Assistant SDK is basically gRPC too. You get efficient typed client libraries in 10 or more languages for free. No reason not to consider it for public-facing endpoints.
I was under the impression that you can't specify fields as null. Instead they just get assigned whatever the default value is for that type.
That seems like a significant drawback for me if it is indeed the case. Especially in the case of a public facing API.
I like the idea of a lot of client libraries able to generate easily, I'm just not sure on this one point how to deal with it nicely...
optional int32 result_per_page = 3 [default = 10];
If the default value is not specified for an optional element, a type-specific default value is used instead: for strings, the default value is the empty string. For bytes, the default value is the empty byte string. For bools, the default value is false. For numeric types, the default value is zero. For enums, the default value is the first value listed in the enum's type definition. This means care must be taken when adding a value to the beginning of an enum value list. See the Updating A Message Type section for guidelines on how to safely change definitions."
Well according to the docs on protocol buffers at least my understanding is as I have read elsewhere.
I don't know what your problem is guy.
My favorite other nicety is forward and backwards compatibility. Having an older binary being able to easily handle the next version of the incoming proto, and also to not loose any of the not-yet-understood fields.
Short blog giving a concrete example: https://www.beautifulcode.co/blog/88-backward-and-forward-co...
Some databases and queues are starting to use this now and it makes it incredibly easy to get started since we can generate our own clients and integrate at whatever level we need.
Edit: spelling
WCF could operate over pipes which was cool for machine local IPC, but beyond that I think gRPC is superior.
But I asked your exact question to the dotnet team and architect David Fowler gave me a decent answer.
> "I don't know that we have a definitive answer as yet and the GRPC experience while great isn't nearly as smooth (as of writing) as the WCF experience. I would say that it's definitely going to be one of the main RPC option of choice going forward but it;s a bit early to say that this is THE blessed new way."
https://github.com/dotnet/core/issues/2278
https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-u...
It was definitely ambitious. When it worked it was sometimes magic, and when it didn't it was a giant mess to resolve.
[ETA: In one past life I made the mistake of trying to use WCF Peer-to-Peer for a project and I still have scars from that. :O]
I personally like sharing `interface.cs` rather than what appears very similar `interface.proto` plus a bunch of tooling.
Ahh well, things go in circles I guess.
"The new thing isn't immediately going to replace the old thing going forward" and then it does.
(And it should. I just don't get why they're always tiptoeing around that same point.)
They are just being non-committal about gRPC being the successor. But I have seen Fowler poking around in the RSocket codebase recently, so who knows.
We worked with a small vendor on a project at work last year, where he was building a frontend for our gRPC based backend system. My team inherited him from another division that was winding down, and though he had weird choices of tooling and frameworks, we couldn't dictate what he used as that was out of our control.
What we imposed though was that he only use gRPC to communicate with our services. He struggled a lot, I spent about an hour with him trying to compile the proto files. He also weirdly converted every message to JSON then XML. I assumed he'd been used to covering from JSON to XML. In the end, we had a poor experience and decided to rebuild the thing in-house.
My observations were that other than unfamiliarity with gRPC, he knows his way around MS stuff, the lack of seamless integration with his technology stack.
This integration should make it easier for people to get productive faster, and for new users to experiment.
Async is not new at all, but classes that really leverage it well might be (pipelines again).
I believe GP is referring to async streams[0]. Notwithstanding the colourful language GP used, I think the new async streams are pretty cool.
[0] https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/gen...
I mean, "slightly more code" - you can say the same about "async ... await" in general, but then it's "insanely more code" and huge potential for error.
It looks that way to me.
i.e. a List<Task<T>> is not the same as an AsyncEnumerable<T>. List<Func<Task<T>>> would be more equivalent, but you needed to have a List<T> which you need to fill beforehand.
You would have to define a few custom types. I have written code that looks something like
Where source is an interface that we have defined. This is not much more complex than an async enumerable.It's definitely possible, and if you save an allocation then that's a step up, but not a game changer for most business process.
Moving data onto and off the network efficiently is (one of) the things that Span<T> was created for.
*) https://devblogs.microsoft.com/dotnet/system-io-pipelines-hi...
gRPC client requires HTTP/2, and HttpClient (the .NET library for making HTTP requests) didn't previously support HTTP/2. The gRPC client actually supports netstandard2.1. Any .NET implementation that supports HTTP/2 should support running the gRPC client.
Kestrel (the .NET web server) already supported HTTP/2 but it required some new features in .NET 3.0 to fully support hosting gRPC services.
<ItemGroup><Protobuf Include="Protos\greet.proto" /></ItemGroup>
Also the code generated goes to obj directory so it's not versioned. I think this is nice way to do code generation, and sidesteps some of the need for type providers in the future for C#.
Very glad French culture is infusing GAFAM (manger means to eat). More seriously, typos like that in the first sentence of a post denotes a serious lack of attention to details.
I never actually feel the need though to actually go ahead and post them. Kindly reflect on what you did, and where this is coming from.