.NET Core gRPC
grpc.io
grpc.io
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.
<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#.
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."
"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.
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.
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?)
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.
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...
Edit: spelling
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.
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...
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
while (! ctx.IsCancellationRequested)
{
var data = await source.GetData();
await Process(data);
}
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.
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.