Build a Microservice App Using gRPC, Python, and Golang (Part 2)

Agus Richard
Nerd For Tech
Published in
7 min readApr 5, 2021
Photo by OMID VISUALS on Unsplash

Welcome back to the second part of this tutorial. We will continue our journey of learning and building an app using gRPC, Python, and Golang. This time, we focus on the implementation details for the authentication service. Let’s start….

Auth Server

First, we have to create the authentication service and the language we use will be Golang. Then, we connect this service to the main service. Now, make sure that you are in the root folder. By the way, if you prefer to separate the services of this project into its own repository, that’s okay. In this case, I will put them together in one repository for my own convenience.

Let’s name this service auth , initialize the golang project and install the required dependencies or you can check how to set up the project here https://grpc.io/docs/languages/go/quickstart/.

go mod init auth      # the name will be auth
go get google.golang.org/protobuf/cmd/protoc-gen-go \
google.golang.org/grpc/cmd/protoc-gen-go-grpc

Now, create the main.go file, then write some kind of placeholder to make sure that we have initialized the app correctly.

Such an original right? :)

Before we start to write some code in a proto file and generate the corresponding code in Golang, we have to set up some configurations and database.

Now, create a database called grpc_auth , we will connect this service to grpc_auth database. Then, create a table called users. This is where the user’s data will be placed every time a new user is registered. You can use this query to create users table.

CREATE TABLE public.users (id serial NOT NULL,username varchar(128) NULL,"password" varchar(256) NULL,CONSTRAINT users_pkey PRIMARY KEY (id));

Make a folder named config and a file inside it named database.go.

Function getDBConnection is responsible to set up the database and ConnectDB is the function which will be imported onto the main file and will be called to establish the connection to the database.

Next, create a folder named repository and a file inside it named user.go . The purpose of this is as the interface that we use to make some mutations or queries to the database. By doing this, I want to implement the concept of separation of concerns within my code.

Inside this file, we created a struct called userRepository and an interface called UserRepository . Then we defined the interface’s methods below it (CreateUser and GetUserByUsername). Notice that we don’t do anything inside these methods, so we have to come back here after we define the proto file later. But, before jump to the next part, at line 31 we have models.User , but what is this thing? Let’s create this ‘thing’.

Make a folder named models and a file inside it named user.go.

Such a short piece of code, right? Here, we just defined the struct that will represent the user.

After that, another piece of code for separation of concerns is the usecase. Create a folder named usecase and a file inside it named user.go . Pretty much the same as repository, but the task is different, you will see.

For now, we leave this usecase file as it is, we will go back here later to implement the real thing.

Now, it’s time to define the proto file and generate the corresponding code in Golang. The generated code will be used as the server part of gRPC, which gives us the response we need when we call some procedure from the client-side (main-service).

Create a file in the root folder named auth.proto.

The above is the content of auth.proto . We are using protobuf language version 3 and the name of the package is auth . Probably you won’t need option, but in this case, I need it or else it will give me an error.

To put this simply, we have to define how a procedure will look like, also with its required arguments and return values. We will use this proto file to generate the server and client of a service. For example, on the client-side, we want to call Register (which is basically a remote procedure), then we have to give it an argument (RegisterRequest) and it will return RegisterResponse .

To generate the procedure code, we have to run this command. But before that, create a folder named auth which will be the target for the output of the generated code.

protoc --go_out=./auth --go_opt=paths=source_relative \--go-grpc_out=./auth --go-grpc_opt=paths=source_relative \./auth.proto

The proto compiler will look for a file named auth.proto in the current directory and will return the outputs in a folder named auth .

After you run this command, you’ll have two files named auth.pb.go and auth_grpc.pb.go . We won’t use this code directly or change anything inside it, in fact, you’ll see a warning at the top of the file said DO NOT EDIT.

Next, create a file named auth.go inside auth folder. Here, we will define how the procedures work.

Again, since we make this service bit by bit we have to come back here to define the real things. In this file, we defined three procedures which are the same as in the proto file definition, because basically here we implement the generated code into something we need it to be. Notice that I put UnimplementedAuthServiceServer , the reason is for forward compatibility implementations.

Now, let’s change the main.go .

Here, we connect to the database, initializing repository, usecase and server, register the service server on line 25, open up the tcp connection on line 27 and serve the server on line 33. At this point, hopefully, you can run this program by typing go run main.go command.

Auth Client

Now, we move to the client-side (main service). First, we have to install the dependency which will be used later to generate the gRPC code in Python.

Inside our main service root directory (make sure you activate your virtual environment first), type this command on your terminal.

pip install grpcio

Next, we need the same proto file from ourauth service. You can copy it into the main service root folder. Then generate the gRPC code by running this command.

python -m grpc_tools.protoc -I. --python_out=./auth --grpc_python_out=./auth ./auth.proto

This command compiles the proto file inside main service root directory (auth.proto) and the outputs are placed in auth folder.

After we ran this command, we have two new generated files called auth_pb2.py and auth_pb2_grpc.py . Likewise the previous Golang service, we have to define the real procedure in another file, let’s call it client.py and place it in auth folder.

This is the part in main service we use to call some procedures in auth service. So this is the client part and the auth service is the server part. Notice that we also defined the same functions as we wrote them in the proto file.

Let’s use AuthClient in the views file. From the previous article, we had defined the auth view functions which were still in a basic form. Now, let’s change it so it implements its real job.

For our convenience, our application will some kind of a mix between gRPC and REST, but in the last article, we will migrate to use templates with Jinja2. The gRPC is used as a bridge to connect between services and REST is used as a bridge to connect between the application and the user.

Auth Service (Revisited)

Now, let’s finish up our auth service. There are several parts we need to change, which is repository, usecase and the server , then create some new utility files.

Change the repository first.

Change the usecase.

To make the above code works properly, we have to create utility functions for hashing password, checking password, generating token, and parsing token.

Let’s update our dependencies so we can generate a hashed password and JSON token.

go get golang.org/x/crypto/bcryptgo get github.com/dgrijalva/jwt-go

Create a folder named utils and a file inside it named hash_password.go .

Next, create a file named token.go inside utils folder.

GenerateToken function is like its name, is for generating a JSON token and ParseToken is for validating a token and also return logged-in user data.

Now, change the server file, auth.go inside auth folder.

Here, we use the usecase which we have updated.

Our auth service is almost finished. To make sure that everything is working properly. Let’s run both services and test them using Postman.

python app.py        # for main service
go run main.go # for auth service

Awesome, now the auth service is done. We will continue how to implement the todo service in the next article. You can find the code for this article here https://github.com/agusrichard/python-golang-grpc/tree/part2.

If you have any questions or feedback, please feel free to leave a comment or contact me by email, agus.richard21@gmail.com. Also, if you think this article help you, don’t hesitate to give this article a clap.

Thank you for reading and see you in the next article.

--

--

Agus Richard
Nerd For Tech

Software Engineer | Data Science Enthusiast | Photographer | Fiction Writer | Freediver LinkedIn: https://www.linkedin.com/in/agus-richard/