Building a RESTful API Using Go with PostgreSQL and Deploying it on SAP BTP

Estimated read time 21 min read

In this blog, we will discuss how to create RESTful API using Go with PostgreSQL and deploying in on SAP Cloud Foundry environment.

You will learn,

How to create and build a Golang application.How to configure and use the PostgreSQL service in Golang using GORM from SAP BTP.CRUD operations using Golang and SAP BTP PostgreSQL service.

Why Go

Go (or Golang) has gained immense popularity among developers for building high-performance and scalable applications, making it an ideal choice for developing RESTful APIs. Here are a few key reasons why Go is an excellent choice for this project:

Performance:
Go is a statically typed, compiled language that is highly efficient in terms of execution speed. Its performance is close to that of C and C++, making it one of the fastest programming languages for building scalable and performance-critical applications, such as RESTful APIs.

Concurrency:
Go’s goroutines and channels make it easy to handle concurrent requests. REST APIs often have to manage multiple simultaneous requests, and Go’s lightweight concurrency model allows efficient handling of thousands of requests in parallel, without the complexity that other languages might impose.

Simplicity and Efficiency:
Go’s syntax is simple and clean, which reduces the cognitive load on developers. It does not have the complexities found in other languages, like class-based object orientation, and comes with a powerful standard library that makes API development quicker and more straightforward.

Strong Standard Library:
Go provides an excellent set of built-in libraries for building web applications and APIs. Its standard net/http package, along with the encoding/json library, enables easy development of robust APIs with minimal external dependencies.

Scalability:
Go was designed to support large-scale applications. When building APIs that might need to handle high traffic loads, Go’s scalability makes it an ideal choice. The language is optimized for large distributed systems, which makes it easy to scale your API as your user base grows.

Community and Ecosystem:
Go has a rapidly growing community and a rich ecosystem of libraries and frameworks. Many tools, libraries, and best practices for building RESTful APIs in Go are readily available, making it easy to implement a robust and maintainable API solution.

Deployment:
Since Go produces statically linked binaries, deploying applications is simple. You don’t need to worry about runtime environments or dependencies on the server, making it ideal for cloud-based platforms like SAP BTP. The resulting binary is small and can be easily run on any system without additional configurations.

Prerequisites

Go Installed – Ensure you have Go installed on your local machine. You can download it from golang.org.

Cloud Foundry CLI – You’ll need the Cloud Foundry Command Line Interface (CLI) installed. Install Cloud Foundry CLI.

SAP BTP Account – Ensure you have an SAP BTP account and access to Cloud Foundry on your subaccount.

Setting up Go Application

step 1: Create your go application using the go mod init {{app_name}}. This command will create a new directory for your project and initialize a Go module.

 

 

mkdir go-rest-api
cd go-rest-api
go mod init go-rest-api

 

 

step 2: Create main.go file and create the app route (/).

 

 

package main

import (
“fmt”
“net/http”
)

func main() {
// Set up an app route
http.HandleFunc(“/”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, “Welcome to My Go Application!”)
})

// Start the server on port 8080
fmt.Println(“Server is running on http://localhost:8080”)
if err := http.ListenAndServe(“:8080”, nil); err != nil {
fmt.Println(“Error starting server:”, err)
}
}

 

 

step 3: Run the app using go run {{filename}}.go. 

 

 

go run main.go

 

 

In browser you can see the app message when you paste the URL.

Create routes, services, models and DB connection files

step 1: Create database service in SAP BTP named, go-crud-postgres. Use the below reference – SAP BTP PostgreSQL Database import to pgAdmin with… – SAP Community

The Bound Applications will be empty initially. It will be updated automatically once deployed this app in SAP BTP.

step 2: Create route, services, model and DB connection files in Go.

Folder structure:

database.go: This file will read credentials from the VCAP_SERVICES of SAP BTP and establish the connection to the database. Also, it will create the respective tables in the database if not exists based on the model provided. Here, user table will be created.

 

 

package db

import (
“encoding/json”
“fmt”
“go-crud/models”
“log”
“os”
“strconv”

“gorm.io/driver/postgres”
“gorm.io/gorm”
)

var DB *gorm.DB

// Get db params from env
func getDBParams() models.DBParams {
appEnv := os.Getenv(“APP_ENV”)

if appEnv == “” {
appEnv = “localhost”
}

// Fetch env values from vcap services since it’s deployed in SAP BTP
if appEnv != “localhost” {
vcapServicesStr := os.Getenv(“VCAP_SERVICES”)
if vcapServicesStr == “” {
log.Fatal(“VCAP_SERVICES environment variable is not set”)
}

var vcapServices map[string]interface{}
err := json.Unmarshal([]byte(vcapServicesStr), &vcapServices)
if err != nil {
log.Fatalf(“Error parsing VCAP_SERVICES: %v”, err)
}

// Ensure vcapServices is not empty
if vcapServices == nil {
log.Fatal(“VCAP_SERVICES is empty”)
}

// Get PostgreSQL services
postgresServices, ok := vcapServices[“postgresql-db”].([]interface{})
if !ok || len(postgresServices) == 0 {
log.Fatal(“No postgresql-db service found in VCAP_SERVICES”)
}

// Get the first PostgreSQL service
firstPostgresService, ok := postgresServices[0].(map[string]interface{})
if !ok {
log.Fatal(“First postgresql-db service is not a valid JSON object”)
}

// Get credentials
credentials, ok := firstPostgresService[“credentials”].(map[string]interface{})
if !ok {
log.Fatal(“No credentials found in the first postgresql-db service”)
}

param := models.DBParams{
Host: credentials[“hostname”].(string),
Port: credentials[“port”].(string),
User: credentials[“username”].(string),
Password: credentials[“password”].(string),
DBName: credentials[“dbname”].(string),
}
return param
} else {
// Fetch values from .env
param := models.DBParams{
Host: os.Getenv(“DB_HOST”),
Port: os.Getenv(“DB_PORT”),
User: os.Getenv(“DB_USER_NAME”),
Password: os.Getenv(“DB_PASSWORD”),
DBName: os.Getenv(“DB_NAME”),
}
return param
}
}

// Connect initializes the database connection.
func Connect() {
dbParams := getDBParams()

port, err := strconv.Atoi(dbParams.Port)
if err != nil {
log.Fatalf(“Error converting string to int: %v”, err)
}
dsn := fmt.Sprintf(“host=%s port=%d user=%s password=%s dbname=%s”,
dbParams.Host, port, dbParams.User, dbParams.Password, dbParams.DBName)
database, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf(“Failed to connect to database: %v”, err)
}

// Migrate the schema
if err := database.AutoMigrate(&models.User{}); err != nil {
log.Fatalf(“Failed to migrate database: %v”, err)
}

DB = database
log.Println(“Database connected successfully!”)
}

 

 

user.handler.go: This file handles /user route with all the REST methods (GET, POST, PUT and DELETE) 

 

 

package userHandler

import (
“encoding/json”
“go-crud/models”
userService “go-crud/services”
“net/http”
“strconv”
)

// UserHandler handles requests for user-related operations.
func UserHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set(“Content-Type”, “application/json”)

switch r.Method {

case http.MethodGet:
idStr := r.URL.Path[len(“/users/”):]
userId, err := strconv.Atoi(idStr)
if err != nil {
users, err := userService.GetUsers()
if err != nil {
http.Error(w, “Failed to fetch users: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(users)
} else {
user, err := userService.GetUser(userId)
if err != nil {
http.Error(w, “Failed to fetch users: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(user)

}

case http.MethodPost:
var userPayload models.User
if err := json.NewDecoder(r.Body).Decode(&userPayload); err != nil {
http.Error(w, “Invalid input”, http.StatusBadRequest)
return
}
createdUser, err := userService.CreateUser(&userPayload)
if err != nil {
http.Error(w, “Failed to create user: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(createdUser)

case http.MethodPut:
idStr := r.URL.Path[len(“/users/”):]
userId, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, “Invalid user ID”, http.StatusBadRequest)
return
}
var updatedUser models.User
if err := json.NewDecoder(r.Body).Decode(&updatedUser); err != nil {
http.Error(w, “Invalid input”, http.StatusBadRequest)
return
}
updatedUserPtr, err := userService.UpdateUser(userId, &updatedUser)
if err != nil {
http.Error(w, “Failed to update user: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(updatedUserPtr)

case http.MethodDelete:
idStr := r.URL.Path[len(“/users/”):]
userId, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, “Invalid user ID”, http.StatusBadRequest)
return
}
if err := userService.DeleteUser(userId); err != nil {
http.Error(w, “Failed to delete user”, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(“User deleted successfully”))

default:
http.Error(w, “Method not allowed”, http.StatusMethodNotAllowed)
}
}

 

 

user.model.go: This is the user model which represents the user table in database with type of each column.

 

 

package models

import “gorm.io/gorm”

// User represents a user in the database.
type User struct {
gorm.Model
Name string `json:”name”`
Email string `json:”email” gorm:”unique”`
Age int `json:”age”`
}

 

 

user.service.go: This file contains the business logics for each API.

 

 

package userService

import (
“go-crud/db”
“go-crud/models”
)

// CreateUser creates a new user.
func CreateUser(user *models.User) (*models.User, error) {
if err := db.DB.Create(user).Error; err != nil {
return nil, err
}
return user, nil
}

// GetUsers retrieves a list of all users.
func GetUsers() ([]models.User, error) {
var users []models.User
err := db.DB.Find(&users).Error
return users, err
}

// GetUser retrieve a single user based on userId.
func GetUser(userId int) (models.User, error) {
var user models.User
err := db.DB.First(&user, userId).Error
return user, err
}

// UpdateUser updates an existing user by ID.
func UpdateUser(id int, updatedUser *models.User) (*models.User, error) {
if err := db.DB.Model(&models.User{}).Where(“id = ?”, id).Updates(updatedUser).Error; err != nil {
return nil, err
}
return updatedUser, nil
}

// DeleteUser deletes a user by ID.
func DeleteUser(id int) error {
return db.DB.Delete(&models.User{}, id).Error
}

 

 

main.go: Updated main.go file to handle the CRUD operations.

 

 

package main

import (
“fmt”
“go-crud/db”
userHandler “go-crud/handlers”
“log”
“net/http”

“github.com/joho/godotenv”
)

func main() {
var err error

//Load .env when run in local
err = godotenv.Load()
if err != nil {
log.Fatalf(“Error loading .env file”)
}

// Connect to the database
db.Connect()

// Set up user routes
http.HandleFunc(“/users/”, userHandler.UserHandler)

// Set up an app route
http.HandleFunc(“/”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, “Welcome to My Go Application!”)
})

// Start the server on port 8080
fmt.Println(“Server is running on http://localhost:8080”)
if err = http.ListenAndServe(“:8080”, nil); err != nil {
fmt.Println(“Error starting server:”, err)
}
}

 

 

Create manifest.yml and deploy the app in SAP BTP using cloud foundry

step 1: manifest.yml with go build options. We included the go-crud-postgres inside the services. So, once the app deployed the PostgreSQL service will be bounded automatically.

 

 

applications:
– name: go-crud
memory: 512M
buildpacks:
– go_buildpack
services:
– go-crud-postgres

 

 

step 2: Deploy the app using cloud foundry

 

 

cf login -a https://api.cf.eu10.hana.ondemand.com

 

 

Enter Email ID and Password and select the space if you have more than one space. Now you can see the space name which is targeted

 

 

cf push

 

 

After the cf push, the go app will be deployed in the SAP BTP, and you can see the application URL in the terminal.

Perform CRUD operations using Postman:

PATHMETHODBODYRESPONSEDESCRIPTION/usersGET [
{
“ID”: 1,
“CreatedAt”: “2025-01-18T09:09:51.995808Z”,
“UpdatedAt”: “2025-01-18T09:09:51.995808Z”,
“DeletedAt”: null,
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
},
{
“ID”: 4,
“CreatedAt”: “2025-01-18T10:09:02.739402Z”,
“UpdatedAt”: “2025-01-18T10:09:02.739402Z”,
“DeletedAt”: null,
“name”: “Vinoth Ari”,
“email”: “vinoth.ari.1@gds.ey.com”,
“age”: 28
}
]Return all the users/users/{{user_id}}GET {
“ID”: 1,
“CreatedAt”: “2025-01-18T09:09:51.995808Z”,
“UpdatedAt”: “2025-01-18T09:09:51.995808Z”,
“DeletedAt”: null,
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}Return specific user based on the user id/usersPOST{
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}{
“ID”: 1,
“CreatedAt”: “2025-01-18T09:09:51.995808Z”,
“UpdatedAt”: “2025-01-18T09:09:51.995808Z”,
“DeletedAt”: null,
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}Create the new user/users/{{user_id}}PUT{
“ID”: 1,
“name”: “Vinoth Ari”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}{
“ID”: 1,
“name”: “Vinoth Ari”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}update user based on the user id/users/{{user_id}}DELETE User deleted successfullydelete user based on the user id

You have now successfully created a Go application and integrated with SAP BTP PostgreSQL service. By using this we implemented a CRUD operation of the users. Also, using the cloud foundry, we deployed this Go app in SAP BTP.

GitHub link: vinoth-ari-ey/go: CRUD operations using GO with Postgresql

 

​ In this blog, we will discuss how to create RESTful API using Go with PostgreSQL and deploying in on SAP Cloud Foundry environment.You will learn,How to create and build a Golang application.How to configure and use the PostgreSQL service in Golang using GORM from SAP BTP.CRUD operations using Golang and SAP BTP PostgreSQL service.Why GoGo (or Golang) has gained immense popularity among developers for building high-performance and scalable applications, making it an ideal choice for developing RESTful APIs. Here are a few key reasons why Go is an excellent choice for this project:Performance:Go is a statically typed, compiled language that is highly efficient in terms of execution speed. Its performance is close to that of C and C++, making it one of the fastest programming languages for building scalable and performance-critical applications, such as RESTful APIs.Concurrency:Go’s goroutines and channels make it easy to handle concurrent requests. REST APIs often have to manage multiple simultaneous requests, and Go’s lightweight concurrency model allows efficient handling of thousands of requests in parallel, without the complexity that other languages might impose.Simplicity and Efficiency:Go’s syntax is simple and clean, which reduces the cognitive load on developers. It does not have the complexities found in other languages, like class-based object orientation, and comes with a powerful standard library that makes API development quicker and more straightforward.Strong Standard Library:Go provides an excellent set of built-in libraries for building web applications and APIs. Its standard net/http package, along with the encoding/json library, enables easy development of robust APIs with minimal external dependencies.Scalability:Go was designed to support large-scale applications. When building APIs that might need to handle high traffic loads, Go’s scalability makes it an ideal choice. The language is optimized for large distributed systems, which makes it easy to scale your API as your user base grows.Community and Ecosystem:Go has a rapidly growing community and a rich ecosystem of libraries and frameworks. Many tools, libraries, and best practices for building RESTful APIs in Go are readily available, making it easy to implement a robust and maintainable API solution.Deployment:Since Go produces statically linked binaries, deploying applications is simple. You don’t need to worry about runtime environments or dependencies on the server, making it ideal for cloud-based platforms like SAP BTP. The resulting binary is small and can be easily run on any system without additional configurations.PrerequisitesGo Installed – Ensure you have Go installed on your local machine. You can download it from golang.org.Cloud Foundry CLI – You’ll need the Cloud Foundry Command Line Interface (CLI) installed. Install Cloud Foundry CLI.SAP BTP Account – Ensure you have an SAP BTP account and access to Cloud Foundry on your subaccount.Setting up Go Applicationstep 1: Create your go application using the go mod init {{app_name}}. This command will create a new directory for your project and initialize a Go module.  mkdir go-rest-api
cd go-rest-api
go mod init go-rest-api  step 2: Create main.go file and create the app route (/).  package main

import (
“fmt”
“net/http”
)

func main() {
// Set up an app route
http.HandleFunc(“/”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, “Welcome to My Go Application!”)
})

// Start the server on port 8080
fmt.Println(“Server is running on http://localhost:8080”)
if err := http.ListenAndServe(“:8080”, nil); err != nil {
fmt.Println(“Error starting server:”, err)
}
}  step 3: Run the app using go run {{filename}}.go.   go run main.go  In browser you can see the app message when you paste the URL.Create routes, services, models and DB connection filesstep 1: Create database service in SAP BTP named, go-crud-postgres. Use the below reference – SAP BTP PostgreSQL Database import to pgAdmin with… – SAP CommunityThe Bound Applications will be empty initially. It will be updated automatically once deployed this app in SAP BTP.step 2: Create route, services, model and DB connection files in Go.Folder structure:database.go: This file will read credentials from the VCAP_SERVICES of SAP BTP and establish the connection to the database. Also, it will create the respective tables in the database if not exists based on the model provided. Here, user table will be created.  package db

import (
“encoding/json”
“fmt”
“go-crud/models”
“log”
“os”
“strconv”

“gorm.io/driver/postgres”
“gorm.io/gorm”
)

var DB *gorm.DB

// Get db params from env
func getDBParams() models.DBParams {
appEnv := os.Getenv(“APP_ENV”)

if appEnv == “” {
appEnv = “localhost”
}

// Fetch env values from vcap services since it’s deployed in SAP BTP
if appEnv != “localhost” {
vcapServicesStr := os.Getenv(“VCAP_SERVICES”)
if vcapServicesStr == “” {
log.Fatal(“VCAP_SERVICES environment variable is not set”)
}

var vcapServices map[string]interface{}
err := json.Unmarshal([]byte(vcapServicesStr), &vcapServices)
if err != nil {
log.Fatalf(“Error parsing VCAP_SERVICES: %v”, err)
}

// Ensure vcapServices is not empty
if vcapServices == nil {
log.Fatal(“VCAP_SERVICES is empty”)
}

// Get PostgreSQL services
postgresServices, ok := vcapServices[“postgresql-db”].([]interface{})
if !ok || len(postgresServices) == 0 {
log.Fatal(“No postgresql-db service found in VCAP_SERVICES”)
}

// Get the first PostgreSQL service
firstPostgresService, ok := postgresServices[0].(map[string]interface{})
if !ok {
log.Fatal(“First postgresql-db service is not a valid JSON object”)
}

// Get credentials
credentials, ok := firstPostgresService[“credentials”].(map[string]interface{})
if !ok {
log.Fatal(“No credentials found in the first postgresql-db service”)
}

param := models.DBParams{
Host: credentials[“hostname”].(string),
Port: credentials[“port”].(string),
User: credentials[“username”].(string),
Password: credentials[“password”].(string),
DBName: credentials[“dbname”].(string),
}
return param
} else {
// Fetch values from .env
param := models.DBParams{
Host: os.Getenv(“DB_HOST”),
Port: os.Getenv(“DB_PORT”),
User: os.Getenv(“DB_USER_NAME”),
Password: os.Getenv(“DB_PASSWORD”),
DBName: os.Getenv(“DB_NAME”),
}
return param
}
}

// Connect initializes the database connection.
func Connect() {
dbParams := getDBParams()

port, err := strconv.Atoi(dbParams.Port)
if err != nil {
log.Fatalf(“Error converting string to int: %v”, err)
}
dsn := fmt.Sprintf(“host=%s port=%d user=%s password=%s dbname=%s”,
dbParams.Host, port, dbParams.User, dbParams.Password, dbParams.DBName)
database, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf(“Failed to connect to database: %v”, err)
}

// Migrate the schema
if err := database.AutoMigrate(&models.User{}); err != nil {
log.Fatalf(“Failed to migrate database: %v”, err)
}

DB = database
log.Println(“Database connected successfully!”)
}  user.handler.go: This file handles /user route with all the REST methods (GET, POST, PUT and DELETE)   package userHandler

import (
“encoding/json”
“go-crud/models”
userService “go-crud/services”
“net/http”
“strconv”
)

// UserHandler handles requests for user-related operations.
func UserHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set(“Content-Type”, “application/json”)

switch r.Method {

case http.MethodGet:
idStr := r.URL.Path[len(“/users/”):]
userId, err := strconv.Atoi(idStr)
if err != nil {
users, err := userService.GetUsers()
if err != nil {
http.Error(w, “Failed to fetch users: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(users)
} else {
user, err := userService.GetUser(userId)
if err != nil {
http.Error(w, “Failed to fetch users: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(user)

}

case http.MethodPost:
var userPayload models.User
if err := json.NewDecoder(r.Body).Decode(&userPayload); err != nil {
http.Error(w, “Invalid input”, http.StatusBadRequest)
return
}
createdUser, err := userService.CreateUser(&userPayload)
if err != nil {
http.Error(w, “Failed to create user: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(createdUser)

case http.MethodPut:
idStr := r.URL.Path[len(“/users/”):]
userId, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, “Invalid user ID”, http.StatusBadRequest)
return
}
var updatedUser models.User
if err := json.NewDecoder(r.Body).Decode(&updatedUser); err != nil {
http.Error(w, “Invalid input”, http.StatusBadRequest)
return
}
updatedUserPtr, err := userService.UpdateUser(userId, &updatedUser)
if err != nil {
http.Error(w, “Failed to update user: “+err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(updatedUserPtr)

case http.MethodDelete:
idStr := r.URL.Path[len(“/users/”):]
userId, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, “Invalid user ID”, http.StatusBadRequest)
return
}
if err := userService.DeleteUser(userId); err != nil {
http.Error(w, “Failed to delete user”, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(“User deleted successfully”))

default:
http.Error(w, “Method not allowed”, http.StatusMethodNotAllowed)
}
}  user.model.go: This is the user model which represents the user table in database with type of each column.  package models

import “gorm.io/gorm”

// User represents a user in the database.
type User struct {
gorm.Model
Name string `json:”name”`
Email string `json:”email” gorm:”unique”`
Age int `json:”age”`
}  user.service.go: This file contains the business logics for each API.  package userService

import (
“go-crud/db”
“go-crud/models”
)

// CreateUser creates a new user.
func CreateUser(user *models.User) (*models.User, error) {
if err := db.DB.Create(user).Error; err != nil {
return nil, err
}
return user, nil
}

// GetUsers retrieves a list of all users.
func GetUsers() ([]models.User, error) {
var users []models.User
err := db.DB.Find(&users).Error
return users, err
}

// GetUser retrieve a single user based on userId.
func GetUser(userId int) (models.User, error) {
var user models.User
err := db.DB.First(&user, userId).Error
return user, err
}

// UpdateUser updates an existing user by ID.
func UpdateUser(id int, updatedUser *models.User) (*models.User, error) {
if err := db.DB.Model(&models.User{}).Where(“id = ?”, id).Updates(updatedUser).Error; err != nil {
return nil, err
}
return updatedUser, nil
}

// DeleteUser deletes a user by ID.
func DeleteUser(id int) error {
return db.DB.Delete(&models.User{}, id).Error
}  main.go: Updated main.go file to handle the CRUD operations.  package main

import (
“fmt”
“go-crud/db”
userHandler “go-crud/handlers”
“log”
“net/http”

“github.com/joho/godotenv”
)

func main() {
var err error

//Load .env when run in local
err = godotenv.Load()
if err != nil {
log.Fatalf(“Error loading .env file”)
}

// Connect to the database
db.Connect()

// Set up user routes
http.HandleFunc(“/users/”, userHandler.UserHandler)

// Set up an app route
http.HandleFunc(“/”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, “Welcome to My Go Application!”)
})

// Start the server on port 8080
fmt.Println(“Server is running on http://localhost:8080”)
if err = http.ListenAndServe(“:8080”, nil); err != nil {
fmt.Println(“Error starting server:”, err)
}
}  Create manifest.yml and deploy the app in SAP BTP using cloud foundrystep 1: manifest.yml with go build options. We included the go-crud-postgres inside the services. So, once the app deployed the PostgreSQL service will be bounded automatically.  applications:
– name: go-crud
memory: 512M
buildpacks:
– go_buildpack
services:
– go-crud-postgres  step 2: Deploy the app using cloud foundry  cf login -a https://api.cf.eu10.hana.ondemand.com  Enter Email ID and Password and select the space if you have more than one space. Now you can see the space name which is targeted  cf push  After the cf push, the go app will be deployed in the SAP BTP, and you can see the application URL in the terminal.Perform CRUD operations using Postman:PATHMETHODBODYRESPONSEDESCRIPTION/usersGET [
{
“ID”: 1,
“CreatedAt”: “2025-01-18T09:09:51.995808Z”,
“UpdatedAt”: “2025-01-18T09:09:51.995808Z”,
“DeletedAt”: null,
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
},
{
“ID”: 4,
“CreatedAt”: “2025-01-18T10:09:02.739402Z”,
“UpdatedAt”: “2025-01-18T10:09:02.739402Z”,
“DeletedAt”: null,
“name”: “Vinoth Ari”,
“email”: “vinoth.ari.1@gds.ey.com”,
“age”: 28
}
]Return all the users/users/{{user_id}}GET {
“ID”: 1,
“CreatedAt”: “2025-01-18T09:09:51.995808Z”,
“UpdatedAt”: “2025-01-18T09:09:51.995808Z”,
“DeletedAt”: null,
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}Return specific user based on the user id/usersPOST{
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}{
“ID”: 1,
“CreatedAt”: “2025-01-18T09:09:51.995808Z”,
“UpdatedAt”: “2025-01-18T09:09:51.995808Z”,
“DeletedAt”: null,
“name”: “Vinoth A”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}Create the new user/users/{{user_id}}PUT{
“ID”: 1,
“name”: “Vinoth Ari”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}{
“ID”: 1,
“name”: “Vinoth Ari”,
“email”: “vinoth.ari@gds.ey.com”,
“age”: 28
}update user based on the user id/users/{{user_id}}DELETE User deleted successfullydelete user based on the user idYou have now successfully created a Go application and integrated with SAP BTP PostgreSQL service. By using this we implemented a CRUD operation of the users. Also, using the cloud foundry, we deployed this Go app in SAP BTP.GitHub link: vinoth-ari-ey/go: CRUD operations using GO with Postgresql   Read More Technology Blogs by Members articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author