DEV Community

ankit-brijwasi
ankit-brijwasi

Posted on

10

Connect FastAPI & Golang services using gRPC

Hello Devs! Recently I started learning Protocol buffers & gRPC, and gotta tell you, this tech is amazing!

THIS POST REQUIRES A PRIOR KNOWLEDGE OF GRPC, GOLANG, AND PYTHON

Follow along with this post to get a hands-on demo on how to establish communication between different microservices that are running on different codebases using gRPC.

Find the code for this post here.

Directory Structure

fastapi-and-golang-grpc-demo
|-fastapi
    |-app
    |-env
    |-requirements.txt
|-protobufs
    |-auth.proto
|-main.go
|-Readme.md
|-go.mod
Enter fullscreen mode Exit fullscreen mode

Create the auth protobuf file

Open the auth.proto file on your favourite code editor, and add the following code to it



syntax = "proto3";
package auth;
option go_package = "auth.utils/auth";


message AuthenticationRequest {
    string token = 1;
}

message AuthenticationResponse {
    int64 user_id       = 1;
    bool  token_valid   = 2;
}

service Auth {
    rpc Authenticate (AuthenticationRequest) returns (AuthenticationResponse);
}


Enter fullscreen mode Exit fullscreen mode

Read more about protocol buffers here.

Add the Go service

1. Initialize the go application with



$ go mod init auth-ms


Enter fullscreen mode Exit fullscreen mode

2. Generate the gRPC code



$ protoc --go_out=. --go-grpc_out=. protobufs/auth.proto


Enter fullscreen mode Exit fullscreen mode

3. Update the dependencies



$ go mod tidy


Enter fullscreen mode Exit fullscreen mode

4. Let's create our gRPC server for golang, add the following code in the main.go file



package main

import (
    "context"
    "flag"
    "fmt"
    "log"
    "net"

    pb "auth-ms/auth.utils/auth"

    "google.golang.org/grpc"
)

var (
    port = flag.Int("port", 50051, "port to run the server on")
)

type server struct {
    pb.UnimplementedAuthServer
}

// extend the rpc service created in auth.proto
func (s *server) Authenticate(ctx context.Context, req *pb.AuthenticationRequest) (*pb.AuthenticationResponse, error) {
        token := req.GetToken()
        log.Printf("Received: %v", token)

        // add some logic to verify token
        return &pb.AuthenticationResponse{UserId: 1, TokenValid: true}, nil
}

func main() {
    flag.Parse()
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))

    if err != nil {
        log.Fatalln("Unable to start the server on port", *port)
    }

    grpc_server := grpc.NewServer()
    pb.RegisterAuthServer(grpc_server, &server{})
    log.Println("Started server at", lis.Addr())

    if err := grpc_server.Serve(lis); err != nil {
        log.Fatalln("Failed to start server at", lis.Addr())
    }
}


Enter fullscreen mode Exit fullscreen mode

5. Start the gRPC server and keep it opened



$ go run main.go -port 8080
2022/11/06 16:26:39 Started server at [::]:8080


Enter fullscreen mode Exit fullscreen mode

Add the FastAPI Service

1. Install the dependencies



$  pip install fastapi uvicorn grpcio-tools~=1.30


Enter fullscreen mode Exit fullscreen mode

2. Generate the gRPC code



$ cd ./fastapi/app/
$ python -m grpc_tools.protoc -I ../protobufs --python_out=. --grpc_python_out=. ../protobufs/auth.proto


Enter fullscreen mode Exit fullscreen mode

3. Create the FastAPI server



from fastapi import FastAPI
import grpc

from compiled_pb.auth_pb2_grpc import AuthStub
from compiled_pb.auth_pb2 import AuthenticationRequest

app = FastAPI()


@app.get("/token/verify/")
def verify_token(token: str):
    # gRPC client for making RPC calls to the server
    channel = grpc.insecure_channel("localhost:8080")
    client = AuthStub(channel)
    request = AuthenticationRequest(token=token)
    response = client.Authenticate(request)

    data = {
        "user_id": response.user_id,
        "is_token_valid": response.token_valid
    }
    return data


Enter fullscreen mode Exit fullscreen mode

4. Start the FastAPI sever



uvicorn main:app --host 127.0.0.1 --port 8000 --reload
INFO:     Will watch for changes in these directories: ['/home/ankit/practice/golang_gRPC/fastapi/app']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [8652] using StatReload
INFO:     Started server process [8654]
INFO:     Waiting for application startup.
INFO:     Application startup complete.


Enter fullscreen mode Exit fullscreen mode

Now, go to, http:127.0.0.1:8000/docs and hit the, /token/verify/ route.

FastAPI server

VOILÀ, As soon as you hit the api request, there will be an internal RPC call to the go gRPC server.

golang gRPC server

Happy Coding!😊😇

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay