>> On today's Visual Studio Toolbox, Sourabh is going to
show us how to build a gRPC service from scratch. [MUSIC] >> Hi, welcome to
Visual Studio Toolbox. I'm your host, Robert Green
and joining me today is Sourabh Shirhatti.
Welcome to the show. >> Thanks, Rob. I'm happy to be here. >> We're going to talk about gRPC. >> That's right. >> You're on On.NET talking about it. You've been on Cloud
Native talking it. It's my turn to get you on
my show to talk about it, but we're going to take a
slightly different approach. We are going to talk
about what it is, but I want to approach
it from the angle less about the underlying
technology and plumbing. I'm the Visual Studio Developer. I've been building
services for a long time. I've built WCF services, I've built web API services. Now, this looks like a new
way to build services. Why? What does it do? Why? What are its advantages? Then what should I do? Should I convert my
existing services? Then how do you actually build one? Because so far the
only demos I've seen, the services are already been built. It turns out, I did not
know this until recently and in 20 minutes, so as all of our viewers are
going to know this, too, that you can actually do
this inside Visual Studio, file a new project,
create a gRPC service. >> That's right. >> Cool. >> That's what we're going to
do. So why was it invented? >> So gRPC is an RPC framework. For as long as I've been alive, people have been trying to make
computers talk to each other and invoke methods on
some other computer. It lends itself well to distributed
systems, things like that. It is a requirement to
scale out effectively. So gRPC comes from
this project that was internally developed at
Google called Stubby. >> Stubby. >> Right. gRPC is the rewrite
slash public version of it. So we chose to build gRPC
support, like first-class gRPC support in .NET because it's one of the most popularly used
RPC technologies today. One of the key things to
keep in mind is when you are talking with other
machines and other computers, not only do you want a rich and robust ecosystem
for your language of choice, you also want to be able to interoperate between other
language text, right? So while we could have
picked something like, say, WCF which is limited
to the .NET ecosystem like good luck getting
that to work with a microservice and then go
running in in Kubernetes. So the benefit of gRPC is it's like a fundamentally
good protocol as well as it's popularly adopted
by many other languages. >> So does it lend itself to one
type of service versus another? So I can think of a service
that you build a web API, a RESTful service to return, the weather or the time. I enter a city and I
get that time back, or a lot of WCF services are written into do crowd
support for databases; select, insert, update, delete. What if I'm doing those
types of services, would I use gRPC for those? >> gRPCs are low-level protocol, so it doesn't lend itself better to, say, weather updates
then crowd applications. So that will be like [inaudible] It lend itself well to both. For fundamental types of calls, you can do with gRPC. You have Unity calls,
which would be I send the request as a client
to get a single response. We have both server
and client streaming, so I can send as many requests as I want and then get back one final response from the
server, or on the flip side, I can send it an
initial request and get back multiple responses
from the server, and also have support for
full bidirectional streaming. So with those primitives, you can pretty much
build most applications. >> So you could just get the
single value back or the CRUD, but it tends to more optimized
for these other scenarios. Is that a true statement? >> I would hesitate to say that. I would say it depends on your domain and what
your application does. Like if I want the weather and the weather is good
for about an hour, there's no point me asking for every 10 seconds no matter how
good the streaming protocol is. So do what's best for
your application. >> But if you want to call a service that tells you number of people
that have walked through the door. I want a service that tells me
when the stadium is half full, and there's people streaming
in, literally streaming in. It would be perfect for something like that. I wouldn't have to
miss for something like that. >> That sounds like a use case, yes. >> Cool. Let's build one. >> So I'm going to hop
over to Visual Studio. I'm actually using your computer, so you no know there are no hacks. >> To prove that there are
no tricks behind the scenes, this is not an internal bill. This is my machine running public
latest version of Visual Studio. >> So we ship gRPC
templates in the box. So we've gone ahead. I picked gRPC. Let's call it GrpcServiceForToolbox. I hit the name but
just to disambiguate. So you see the gRPC demo. So this is actually the Visual
Studio new project dialog discovery templates
installed by the .NET SDK. It ships the part of the
SDK, even though today, we're focusing on the Visual
Studio support and how to do it. If you were using a Mac like I do, then you'd be able to
do the same thing. I'll do it from the command line. >> You could put it in
a container, I see. >> Yeah. So let's keep
it simple for now. >> Keep it simple.
That's good to know. It says something about
supporting .NET Core. >> Right. So the gRPC library that we're talking about here is gPRC.NET. There's actually another
implementation with gRPC for .NET. This was one of the
original libraries authored by couple
of folks at Google. While they both work, we're going to be
focusing on gRPC.NET because we think that's the
more defined experience. However, this is limited to
.NET Core 3.0 and above. So keep that in mind. If you
want some interoperability, maybe you need some Xamarin support. You may be forced to take a look
at those authored libraries. Some of the tooling that
I'm going to show you works irregardless of which
gRPC library you use. It may prod you in the direction of using
libraries we think are better, but some of these pieces will work. >> Okay. Cool. >> So let's see. So right off the bat, if you're
familiar with ASP.NET Core, you would recognize this as
an ASP.NET Core application. We have Startup.cs, Programs.cs. It looks like a regular
ASP.NET application. I do want to bring your attention to this directory here called Protos. So in here, we have a
file called greet.proto. So this is a Protobuf file. >> What is a Protobuf? >> So Protobufer is short
for Protocol Buffers. It's the IDL, the interface
definition language used for gRPC. >> So it defined as the service in what it's expecting and
what it's going to return. >> Exactly. So as you can see, let me highlight an area of interest. That's the actual service
definition with the RPCs. This is Unity RPC call, so single requesting or
response and you can see, it's defined in terms
of message types. You'll also see that the message type definitions
are contained here. So the way you start
with the gRPC services, you probably first author
your interface definition. Once you do that, you want to
hook it up into MSBuild and say, "Hey, use this to generate stubs that I can use to
go write a service or a client." So on the service, you get
the service stubs that you can fill out the implementation for. On the client, you get a
full functional client but you can go and invoke calls on. So once we have authored this file, what we go ahead and do is, I'm going to get your
attention to this menu. I'm going to go into
right-click on my project. I click "Add", and there's an
option called "Service Reference." So you can see that this
document is already referenced. It says, "Hey, this was greet.proto, it's a reference to a document and the type of code
generation was the server." Because in this project, I'm implementing the service side of it. What we'll do after this is go
implement a client as well that actually invokes the service
implemented by this, and then points to the location. You could easily go point it, create another a new proto
file and hook it up. This is the preview UI over it. If we actually drop down
to the project file, you can actually see
what's happening. So we're actually linking
to this directory, Protos/greet.proto and we're
seeing generated service. So you can generate only the
message types server client report. So once we've done all that, let's actually go
look at our startup. Our program remains
pretty much unchanged. You go to startup, you'll
see a couple of things. You will see in ConfigureServices, I make a call, the AddGrpc.
You need to do that. Then the other thing in
my configure method, and I'm actually building
my app [inaudible] out. In my endpoint routing, I have this, endpoints or MapGrpc. We haven't done any reflection, e-Magic, like we do in the case of MVC where we do controller discovery. We've suggested that you
create a directory called services and purchase service
implementation in there, but that's just a convention. But what you do need to do, is actually registered each of
these services in your application. Then, speaking of this,
I've obviously registered. So I do want to point out one thing, you do not see any path or URL because gRPC is an
opinionated protocol. >> What does that mean? Because I've been that's
used to being opinionated, but I don't think it
means the same thing. >> I think it tries to take a
lot of ceremony away from you. In large scenarios, that's extremely helpful because it makes
you more productive quickly. When I map the scene,
I didn't have to think about what's the path on
which is going to be served, what's the path base, how do I communicate
that to a client. As long as the client knows that this is where my gRPC endpoint exists, everything else is built
into the protocol. >> Okay. >> So let's go in and actually
look at this service definition. Oh shoot. Sorry, I realized you didn't
have function lockout. >> So now we're in the- >> The actual service implementation. >> -GreeterService. >> So one thing you
will notice right off the bat is this GreeterBase. So there's some magic
that we skipped over. But when you did the entire
gesture in Visual Studio to add a service reference
to a proto file and ask it to generate stuff, it actually did some magic
and generated stuff. So this actually lives in
my [inaudible] folder. I can go over into this, but this is generated code. >> Yeah. Okay. >> So not only do I have
generated code for the service, I also have it for the message. So it also contains code on how to
serialize, deserialize messages. So when I can move my experience as a developer, I go into
my service definition and I can just override the
rpc methods that I want. Let me show you an example. If I hop back over here, let's do this. I'm going to create another rpc, let's call it SayHello2, so we don't have any conflict. All I did is I hit "Save," right? Now we have the design time building Visual Studio happening under
the covers, and I save. So if I come back
over into this file, I'm going to go. Do you see this? >> I do. There it is. >> So I get SayHello2, and I
already have the overwrite. So that was the integrated
design-time build experienced in Visual Studio that allows you to be super productive when
you're quickly [inaudible]. >> Yeah, that it knew to do
the task HelloReply for you; you didn't have to type that. >> Yeah. >> Sweet. >> So that's some fun stuff we did. So now after having looked
at all these codes, the thing you'd be curious
is, how do I run this? How do I see what's going on? So I'm just going to go
ahead and run this project. So this is also a point
for us to sanity check. Make sure I didn't click it
down and mess something up. >> So you ran by just F5? > > I just hit "F5." >> Okay. Because I noticed
there wasn't a Run button. >> Right. So if you look at the logging again, very similar to what we see
in [inaudible] it says, "Now listening on localhost 5,001. >> Okay. >> So let me copy that, and is it safe to use this browser? >> It is safe to use Edge. Yes, it is. [inaudible] Edge. >> So it's got to read
what it says here. >> Well, good news
is it talked to it. >> Yeah, it says communicates with gRPC endpoint must
be made to a gRPC client. >> Okay. >> Which makes sense. I opened it in the browser, but this
isn't in web app. >> Right. >> But because we were built
on top of ASP.NET Core, it's just a friendly thing we put
it in the templates to warn you. So for folks who are trying this, I would highly employ you
you actually go to CFW link. What we'll do in the
rest of the day is walk through how creating
a client looks like. But for folks trying it at home, tutorials are operated and
they should follow that. >> Cool. >> So now that we have
this running and we've established that we
need a gRPC client, let's actually go
through the experience of creating a new project, adding in a client and
then making a [inaudible]. >> So there is a run button? >> Yeah. >> Okay, I don't know
why missed that. >> So let me go into my solution. I'll add a new project. We don't need it to
do anything fancy. So I'm just going to add a console. Nearly click on that
vv there for a second. So far, I mean, it's good. Now we're going to make use of that service reference
experience that I spoke about. >> Because this is just
a service, and you want to reference it. Because I'm
seeing that service reference. >> I'm going to go ahead
add Service Reference. >> Because it's in the same
solution it should know about it? >> No. So you have to
express the point. >> Okay. >> So I have to point
to the proto file. I just want to show one thing
before I click on this. Do you see there's also URL? >> I do. >> So if your company
publishes your proto files, that is central location, or you take any dependence on
somebody else's service, like you have a microservice team and you need to call
somebody else's service. You can actually point at
the URL, and Visual Studio will keep the URL handy and then
you can refresh it if you need be. >> Okay. >> So I'm actually going to point. So we're going to work up this directly and then in
the protos directory. So again, this is a convention based. If you want, you can move it into the solution item. They're
both the project, excuse me, utilize. >> Yeah. >> Point it at that, and then remember how I mentioned
you can do any of these. >> Yeah. >> Since we're going to use
this to the client, let's actually go ahead and
generate a client. So we need a couple of packages. So the tooling is intelligent traits. It adds the service reference as well as brings in the
package dependencies. So it says this is good. Let's actually go ahead and look at the CSProj to see what
exactly happened. So you can see it brought
in Google.Protobuf, gRPC.NET.ClientFactory,
and GRPC.Tools. >> Okay. >> So this is everything
that we need to actually make the one and call. So shall we go ahead and write some code to actually
make one and call? >> Sure, yeah. >> So the first thing
we need is a channel. So think of channel as the
underlying connection. I'm using var syntax
because it's really nice. I believe we have static
helper method that hangs off. So we start getting using
somebody else's keyboard. I might not have gone
into great detail, but I know the service is
listening on localhost 5,001, at least that where we
configured it to, right? >> Right. >> So let's do that. Now, once we have a channel, we can new up a client
and give it the channel, so I will do. Now we parsed in the channel. Now, once we have a channel, we can actually invoke HelloAsync. You see HelloAsync too as well because we've added
it to the Proto file. >> Yeah. >> Obviously, it's not implemented. Then let's just go look at
this method definition. Why do we have to
parse the HelloAsync? We need to parse it a request. It needs a HelloRequest. >> Okay. >> If we go back to message file, just to remind ourselves,
HelloRequest just took a name. So I'm going to jump
back over to my code. >> It's not finding
HelloRequest. There we go. >> There we go. Let's do Robert,
if I can spell your name. Then I should just be
able to do a call. This call, this actually is an async. We generate both the synchronous
and asynchronous methods. It's a recommendation
that you do this. >> You can use the
semicolon at the end. >> Yes. C#, is it 7.2 has async mean? >> Yeah. >> Yeah. The challenges of
using someone else's machine. >> Well, that's why
I gave you a mouse. >> You're talking to
someone who uses a Mac. I'm just going to put
it in a Console.ReadKey then so it just doesn't close on me. >> Okay. >> So things look good to me. I can go ahead and build. All right, so let me go ahead. So this should start
debugging the service. Now, we also want to
launch the client, so let me go into the client. >> Hello. There we are. >> Here you should
see Request finished, Executed endpoint,
greet.Greeter, and SayHello. This is also something
I was talking about, like how the URLs are
convention lists. So it's PackageName, ServiceName, and then RPC method. I didn't have to figure all that out. It worked for me. The only thing which might
be worth looking at is, it's just to remind ourselves
that we're actually calling a method from one application
into another one, and we're able to call it as
if that was in the same thing. That's the goal of RPC, if you will. So I can actually go ahead and maybe, say, put a break point in here, as well as put a break
point in my service, just to show you what
that feels like. So I go ahead and run this again. Let me debug this as well. If you're doing more development, you can use Visual Studio and
start multiple start-up projects since we did a couple of executions. So you can see I have the
break point on my client. If I hit "Continue," we should see now I have the
break point in my service. >> All right. >> So it's a nice experience
for developing services. >> Then now that this is perfect, it's been tested rigorously, we're ready to go. We just publish it to Azure, and we move on, right? >> There are certain
challenges there. So while gRPC builds on existing technologies
like Protobuf and HTTP/2, it actually uses, let's say, the full gamut of features
supported by HTTP/2, something that not all HTTP/2
implementations support today, which means if you're
running anywhere in a hosted service where you go through a proxy or something like that, you really need to make
sure that everyone up into that point supports
full fidelity HTTP/2. So we're currently working
closely with the Azure team. We hope to get there soon. But it is a change because
it requires a change to the [inaudible] HTTP driver in
Windows, like HTTP.sys, and then we have to work
our way up the stack. So I think takeaway for people
is we're working on it, but it is a big project and I
can't tell you when it'll be done. >> All right. Fair enough. >> But you can deploy it, the Azure Kubernetes service. >> All right. >> It's just not on Azure App Service because they have some proxying
going on in front for you. >> Great. So we accomplished
what we wanted to accomplish. We reviewed what gRPC is, talked a little bit about
some of the scenarios, and then most importantly, saw that right now, you can build one from File New
Project in Visual Studio. Awesome. >> I do want to show one more thing because you have that voice
like we're about to wrap up. >> That is my
we're-about-to-wrap-up voice. >> I just want to go over into
the docs and point out that we have our docs for Remote
Procedure Call Apps. So this has the full
introduction and tutorials. >> Perfect. Nice. >> It covers a lot of things, practices, backgrounds,
and things like that. So please check out the
extensive documentation. >> Absolutely. We'll
put a link to that in the show notes. Thanks so much. >> All right. Thank you. >> I hope you guys enjoyed that, and people should try these out
and start experimenting with them. Get used to them
because this is coming, this is here, and this will
get more and more powerful. >> You did say coming, but these are production-quality
libraries that have been shipping with a non-preview moniker, if you will, since 3.0. We're about more than
six months in, I guess. >> All right. So this is here. This is our viable option. >> Absolutely. >> People should check it out. Thanks, and we will see you next
time on Visual Studio Toolbox. [MUSIC]