Build a gRPC server with Go - Step by step tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to this session in this video I'm going to show you how to create a grpc server with go let's get started in order to initialize my project I'm going to initialize a go module to do that I'm going to open the terminal and then inside my terminal I'm going to type go mods init and then my module pass so github.com slash Maximilian Honduras slash demo Dash grpc as Azure you will have a go.mod file that will be created at the top you will have the module paths so module keyword and then the module pass and then the version of go that you are using the first file that I'm going to create is the protofile what is the protofile this will be the description of your API of your interface so I'm going to create a new file and I'm naming that invoicer dot Proto so inside this protofile I'm going first to Define which syntax to I use so I write syntax and then equal Proto 3 and why do we need to specify that that's because when we have a grpc service the messages that we will exchange between the server and the client will be encoded using protocol buffers and these are protocol buffers as the versioning system and we see here explicitly that we are going to use the version 3 of protocol buffers then I can Define my service so I'm going to write service and then I have to bet the service name so it should be invoicer and then I have a curly bracket and here inside I can Define my endpoints I can Define my RPC methods so I start by RPC and then I put the name so create and then I open parentheses and inside the parenthesis I should put the request so it's I will name that create request and then I put returns and then I will have to specify my return so my return will be a create response message so we have a create request message and it creates response message but those messages they do not exist for the moment that's why it's in Red so we have to create them let's go so I create my first message type create request and here I will put the fields that I can have in this message I will also create right away my create response then I need to Define what is inside my create request which is inside my input and what will be inside my output so let's begin by create request so first I want to have an INT 64 that will be named amount that will be at the position 1 of my message so I need an amount for an invoice but not only an amount I also need a currency so I add a currency here currency is a string and it will be in position 2. uh by the way you can see that I use amount as integers that's because I'm using the folder pattern which is to represent an amount of money with an integer which is X Prime in the smallest unit of the currency and occurrence as a string so I have my amount and currency then I can have my create response that will be composed of bytes and I will want to put for instance an invoice as PDF so I create one field here that is of type bytes the name is PDF at position one and maybe also I want to have the invoice as a doc file so I can add another field what I can also do is create other messages so let's create a message named amount then I open a curly bracket and then I can put that here so I have a message amount and inside my message create request I can put another message inside and let's say that I put a message of type amount that I name amount and it will be at the position one this is very useful if your messages start to be very large or if you want to reuse some messages that you have defined elsewhere so then in my create request I have also to save from which person is the invoice so I add a string field from position 2. and I add another field which is 2 at the position 3. all right so we have our service invoicer that takes a create request and returns a create response there is just one thing missing here is an option and I put at the top of the file so you can put several options if you want what I can do here is add the option go package and here I have to specify the path of my go package so I start by the module path so github.com maximinia Honda slash demo Dash grpc by the way this is the same thing that you should have here and then I put a slash and the package name I'm going to name that package invoicer and then I don't forget the semicolon so I add this option in order to tell the program that we are going to use in order to create um code where to put that code now we have our protofile ready and in order to make it work we will need to generate the code for the server and the client so in order to do that we will use something called protalk or protoc and you will need to install it before so you can go on this page so jrpc.iu dogs slash protalk installation and you have instruction for installing that so if you're using Linux you're gonna run that protobuf compiler or if you're using Mac you we need to run that command so Brew install protob it's pretty easy to install you can also choose to insert a pre-compiled binary and then you have the instructions here I find that I'm using Mac OS so this one is really easy to run um so once you have done that you should have the access in your terminal to Proto C product so in order to check that you're gonna run product Dash version and then press enter and you can see here that is installed and I have the version 3.15.2 so that's cool now that we have product we will be able to generate some code based on this protofile and we will generate the code that will take a message and uncode it in the protocol buffers way and also decode it and we will also generate the code in order to create our grpc server now I open my terminal and I type product and then backslash I add a backslash in order to go to the next line in order for you to follow me more closely you can also write the command in one single line but it's not very visual so I'm gonna add a first option which is dash dash go underscore out here I have to say the package name that I want my code to be generated in so invoicer I want to that to be generated into the package invoicer then I'm going to add a new option so go underscore opt and then equal pass and then equal Source relative it simply says that the file that will be generated will be in the same relative directory as the input file in the input file is the protofile right so I can now add another option it's go Dash grpc underscore out and I'm going to put invoicer as well I want my grpc code to be generated into the package invoicer and then I add another option it's go Dash grpc underscore opt and that will be equal to pass equal Source relative and then I have to specify my input file and the input file it's the invoicer dot Proto my protofile and then I can press enter we have an error it says invoicer no such file or directory that's because we need to create a new directory here named invoicer and then I can try to run the command again and it seems to work so we have two files that have been created I find them invoicer.pb.co and a random invoicer underscore grpc.pb.com what we can note here in those files is that it relies on some external code I have an import statement here and so it use the package context okay it's passed from the standard library but those packages are located elsewhere here we have the same in the invoicer.pb.com so what I'm going to do is that I'm going to do a go get on this package in order to download it and use it in my program so I open my terminal and then I type go get Dash u in order to get the latest version of that so the google.golang.org jrpc package has been downloaded and you can see that we have some changes on the go mode you can see that we have these these and this this that has been added and you can see that we have also indirect dependencies here I'm going just to run a go mode ID I run comat's ID because I've seen that all the dependencies were noted as indirect and the government ID command will ensure that the go mode file matches the source code in the module so no you can see that I have those two that are not indirect but direct and those that are indirect so it's better and you can see we have no more red here so it means that my idea has found the sources of those code and to go mode is clean and now we can write our main.go file so I create a new file in the root directory and then I name that main.co uh so you can see I have a package man in the function man so this is the entry point of my program since I want to build a grpc server I have to open a connection in order to receive requests and send responses in order to do that I have to call net.listen so net is a standard package from the standard library and it will take as first parameter TCP and then we have to give the address so we are going just to give the port so here I say that I want to do both 80 89 so you can put whatever you want here and nets.listen will return a listener and an error so we are going to call that list Now list and then an error so the first thing that I have to do is I have to check if I have an error so if error different than nil so if I have an error I want to exit my program so I'm gonna call log.thatter and I'm going to say that cannot or at least create cannot create listener and then I put the error message that I receive so percentage s and then error but here it doesn't work I want to print something here so I'm gonna use log fatalef so with lock for the left percentage s will be replaced by the text of the error that I got it's better to debug once I've done that I can call invoicer Dot register invoice or server and so that method has been generated by protoc and so it takes as first argument a service producer or grpc service register and our server and if I look at what is that it's a type that is a part of this package that we have imported before so in order to create my grpc service Mervis raw I'm going to use a method from the grpc package so grpc dot new server so this will be my server and so I can use that as the first argument and as the second argument uh I have to give an invoicer server let's take a look at this type and you can see that this type is an interface and so you have one method on that interface which is create that takes first argumental context then a create request and a create response and then we have this sounds familiar no so it's on create request and response that we have defined in our Proto file so what we have to do is we have to create a type that implements this interface invoicer server all right so let's do that I'm going to split the view here in order to have my interface displayed so I come back to my main dot go and now my task is to implement an interface so what does it mean to implement an interface it means to create a new type that has the methods that are defined is this interface so let's do that I create a new type so let's call it my invoicer server I base that on a struct could also put another type if I want and then I have to Define some methods and those the methods that I have to Define is the first this one so create so I'm going to add a new method here and so my type would be my invoice or server the receiver name let's call that s because it's a server like a server so the name of my meter should be created and it should take context and a create request so what I'm going to do is I'm going just to copy that and replace that here also I have to import some stuff here so I'm going to import the context package from the standard Library and then this type create request is about out the invoicer package so I built invoicer.create request I'm going to do the same for the create response so no we have this method create here and let's return something dummy um so we can return Neil and nil but we will return a new element of type pointer to invoicer Dot create response and then we can fill the feeds so for instance that the field PDF is of type slash of bytes so I'm going to create a slice of slice of byte here I can do the same for the dockings the type my invoicer server does not fully implement this interface here you have something a bit weird here is that you have a type invoice or server you have a first meter to create we implemented it and then another method must embed and implemented invoicer server so it's here to Signal you that all the implementations of this invoice or server must embed and implemented invoice or server for forward compatibility so we're gonna do that we're gonna embed that type here so to do that I'm going to just embed the type and implemented in voiceover server like that and you can see here that my ID has automatically deleted that this type implements this interface I can create now a new variable service that will be of type pointer to my invoicer server and I will put that service variable a second argument of the register invoicer server that's because invoices server is a type interface and the point of an element of type pointer to my invoice or server implements this interface my service is not registered I have no to launch my server so I will use a method that is defined an element of type pointer to grpc.server and this method is called serve and you can see that serve takes an input and this is a net dot listener that we have created just here so I will put the address here and by the way you can see that it can return an error so I have to handle that error again it's the same pattern if they are different than new then I can use log dot fatalef and I would say impossible to serve and then I will print the error message to percentage s and then second argument error all right so we are ready to launch the server so I go into my terminal and then I can run go run main dot go I can also click here just to run it locally let's try with the terminal so Goran main.co if you use Mac OS you will see this alert so do you want the application main to accept incoming network connections that's normal we are opening a network connection so you have to click hello in order to allow that and then your server is launched you might ask me how to test that so in order to test the server you should be able to create a message on code it with protocol buffers and then send it to the server it's not that easy to encode a message into the protocol buffer format and in order to do that you will need to use a tool in order to test your grpc server so what I use is Bloom RPC in order to send my request to grpc server when you have installed Bloom RPC and you open the application you will have this window the first thing that we are going to do is to load the protocol buffer file because bluemere PC we need that value to encode messages into the protocol buffer format so I'm going to click on import protos and then I select my protocol buffer file so room FC will pass that and you will see that you have your method here and it will generate for you an example of request that is in Json format and then you will be able to launch your request so you have to make sure that you have localhost 8089 or whatever you put as a bot and then you can send a request by clicking the play button and you can see here that we have a response from the server so I can try to run as many requests as I can as I want so I will have the same answer because for the moment it's static all right so our server is working and what I do generally when I work with grpc project is that I create a make file at the root of the project and in this make file I will put the command in order to generate the code um so in a make fan what you do is that you write the receipt name so it's also called the target name and I'm coding that for instance generate grpc code then a colon and then I'm going to put my product command I put the command just here so I've copied that so it's product dash dash go out etc etc and then inside my terminal what I can do is I can run that Commander to regenerate my code so let's say I do modification in my protofile I have to regenerate my code so make generate grpc underscore code now let's say that I want to add another field to my create request my field of type string for instance like vat number which will be at index 4. then I can open my terminal and run the command then if we take a look at the create request type you will see that you have another field vat number of type string and by the way in our main dotical file we have this method and that takes a context.context and an invoicer.create request but we didn't Define name for input variable so we can do that now so CTX for context and then rake for the request and then I have access to the context and the request so what I can put here instead of test I can put what I have in from for instance then we can run our server again so go run main.co and we will test that with Bloom RPC so I allow the connection then I can launch Bloom RPC let's launch one new request and you can note that each of those numbers represent the ASCII value of hello the later let's take a look at the ASCII table if I take the letter H it's 72 and here I have 72 then I take the letter e not capitalized and you can have e capital s which is 69 or the e um that is not capitalized that is 101 and you can see that we have 101 here etc etc what you can do next is to really Implement that create method so generating an invoice and returning the PDF bytes for the invoice you can also do the following is to add a new method here for instance update if you want to update an invoice I don't know if in accounting way it's something doable but we never know we can also have a delete request so you will just have to add another line then change the name etc etc this is the end of this session so what do you need to remember the first step when you want to create a grpc server is to create a file.proto that would be the definition of your interface the definition of your API you will Define messages you will Define a service with RPC methods this is the end of this session so what do you need to remember the first step when you want to create a grpc server is to create a file dot Proto you will Define messages Define a service and inside a service you can have RPC methods then you will need to generate the go code that will be used and you will use protalk to do that the code that will be generated will help you to on code and decode messages with the protocol buffers format to handle also incoming grpc requests and two answers those requests then you have to remember that each time you change your protofile then you need to regenerate the code then another advice do not touch the generated code your transient will be removed at the Next Generation that's it thanks for watching so you can read my book on practicalgressions.com and I also have a cocus of 32 hours with a real world project on that website you can follow me on Twitter LinkedIn and YouTube thanks for watching and see you next time
Info
Channel: Maximilien Andile
Views: 32,933
Rating: undefined out of 5
Keywords:
Id: gbrPMv_GuQY
Channel Id: undefined
Length: 26min 33sec (1593 seconds)
Published: Mon Nov 21 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.