DEV Community

Cover image for Building a Microservices Cloud Backend using Go and PostgreSQL
Marcus Kohlberg for Encore

Posted on • Updated on

Building a Microservices Cloud Backend using Go and PostgreSQL

😬 Building microservices applications can be a pain. Normally you need to deal with a lot of boilerplate, and it can be hard to ensure end-to-end type-safety.

πŸ’‘ This guide shows you how to deploy a fully type-safe microservices application in Go β€” implementing the backend for a Trello application as an example.

This is what our backend architecture will look like, consisting of two services each with their own PostgreSQL database:

backend architecture

To build our app, we'll be using Encore, a backend development platform that provides a type-safe Infrastructure SDK for declaratively defining infrastructure in Go code.

We'll then use Encore to automatically provision and deploy our application.

πŸš€ What's on deck:

  • Install Encore
  • Create your backend app from a template
  • Run locally
  • Deploy to Encore's free development cloud

πŸ’½ Install Encore

Install the Encore CLI to run your local environment:

  • macOS: brew install encoredev/tap/encore
  • Linux: curl -L https://encore.dev/install.sh | bash
  • Windows: iwr https://encore.dev/install.ps1 | iex

πŸ”¨ Create your app

We'll be starting from a template that has two services, each with a couple of API endpoints and their own databases. (See the architecture diagram above.)

When you have installed Encore, create your application from the example app using this command:

encore app create my-app-name --example=trello-clone
Enter fullscreen mode Exit fullscreen mode

🏁 Run your app locally

Before running the application, make sure you have synced the project dependencies by running go mod tidy from the project root folder.

Also make sure that Docker is installed and running, it's required when running Encore applications locally that use SQL databases.

With that out of the way, let's start the application using this command:

encore run
Enter fullscreen mode Exit fullscreen mode

You should see this:

Image description

πŸ•Ή Open the local development dashboard

While encore run is running, open http://localhost:9400/ to view Encore's local developer dashboard.

Here you can see automatic API documentation, try your APIs with the API explorer, and study your application behavior using Encore's built-in distributed tracing.

Local development dashboard

πŸ“ž Call the API

Now that your app is running, you can ping the board.Create endpoint to create a Trello board. Either from the API explorer in the local dev dashboard, or using cURL:

curl 'http://localhost:4000/board.Create' -d '{"Name":"my board"}'
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ Once you've called the API, you can view a trace of the request from the local dev dashboard.

trace in local dev dashboard

πŸ€” How it works: Defining API endpoints

Let's take a look at the code implementing the endpoint we just called:

// Create creates a new board.
//encore:api public
func Create(ctx context.Context, params *CreateParams) (*Board, error) {
    b := &Board{Name: params.Name, Created: time.Now()}
    err := sqldb.QueryRow(ctx, `
        INSERT INTO board (name, created)
        VALUES ($1, $2)
        RETURNING id
    `, params.Name, b.Created).Scan(&b.ID)
    if err != nil {
        return nil, fmt.Errorf("could not create board: %v", err)
    }
    return b, nil
}
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ With Encore you define API endpoints by adding the //encore:api annotation to any normal Go function. At compile time, Encore then generates the boilerplate code necessary to turn this into a real API endpoint. (Learn more in the docs)

πŸ€” How it works: Creating microservices

With Encore you create a microservice by defining one or more APIs within a regular Go package.

Encore recognizes this as a service, and uses the package name as the service name. When deploying, Encore will automatically provision the required infrastructure for each service.

On disk it might look like this:

/my-app
β”œβ”€β”€ encore.app          // ... and other top-level project files
β”‚
β”œβ”€β”€ hello               // hello service (a Go package)
β”‚Β Β  β”œβ”€β”€ hello.go        // hello service code
β”‚Β Β  └── hello_test.go   // tests for hello service
β”‚
└── world               // world service (a Go package)
    └── world.go        // world service code
Enter fullscreen mode Exit fullscreen mode

πŸ€” How it works: Making API calls

Calling an API endpoint looks like a regular function call with Encore. Import the service package as a regular Go package using import "encore.app/package-name" and then call the API endpoint like a regular function. Encore will then automatically generate the necessary boilerplate at compile-time.

πŸ’‘In the example below, we import the service package hello and call the Ping endpoint using a function call to hello.Ping.

import "encore.app/hello" // import service

//encore:api public
func MyOtherAPI(ctx context.Context) error {
    resp, err := hello.Ping(ctx, &hello.PingParams{Name: "World"})
    if err == nil {
        log.Println(resp.Message) // "Hello, World!"
    }
    return err
}
Enter fullscreen mode Exit fullscreen mode

πŸ’‘This means your development workflow is as simple as building a monolith, even if you use multiple services. You get all the benefits of function calls, like compile-time checking of all the parameters and auto-completion in your editor, while still allowing the division of code into logical components, services, and systems.

Then when compiling your application, Encore uses static analysis to parse all API calls and compiles them to proper API calls.

πŸš€ Deploy to the cloud

Commit the new files to the project's git repo and trigger a deploy to Encore's free development cloud by running:

git add -A .
git commit -m 'Commit message'
git push encore
Enter fullscreen mode Exit fullscreen mode

After triggering the deployment, you will see a URL where you can view its progress in Encore's Cloud Dashboard.πŸ‘ˆ

It will look something like: https://app.encore.dev/$APP_ID/deploys/...

From there you can also see metrics, traces, and connect your own AWS or GCP account to use for production deployment.

πŸŽ‰ Great job - you're done!

You now have the start of a scalable Go microservices backend running in the cloud, complete with PostgreSQL databases.

Keep building with these Open Source App Templates.πŸ‘ˆ

If you have questions or want to share your work, join the developers hangout in Encore's community on Discord.πŸ‘ˆ

Top comments (8)

Collapse
 
adesoji1 profile image
Adesoji1

Gopher 😊😊😊😊😊😊😊πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯😊😊😊😊πŸ’₯πŸ’₯πŸ’₯πŸ’₯πŸ’₯πŸ’₯πŸ’₯

Collapse
 
tsolan profile image
Info Comment hidden by post author - thread only accessible via permalink
Eugene

Too many abstractions with this Encore. Definitely not a go style.

Collapse
 
marcuskohlberg profile image
Marcus Kohlberg

gopher lol

Collapse
 
tsolan profile image
Eugene • Edited

Feature for feature’s sake. It’s hardly compatible with std. Isolated product. Trash.

Thread Thread
 
marcuskohlberg profile image
Marcus Kohlberg

just use the std library

Thread Thread
 
tsolan profile image
Eugene

It’s definitely time to refer database installation as a decisive factor in development. Get it running in no time, then spend tens times more to figure out how to hook it up to other libs/services. Productivity is off the charts. Please continue, sir!

Thread Thread
 
marcuskohlberg profile image
Marcus Kohlberg

Image description

Thread Thread
 
tsolan profile image
Info Comment hidden by post author - thread only accessible via permalink

100500 posts about nothing, how to deploy hello world with Postgres in cloud using the pet project (another clone of existing ones) you’re trying so hard to promote. Clown.

Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more