Final Project: Build a Complete Backend in Golang
Overview of Your Project
You'll be building a blog backend that allows:
- Creating a blog post
- Viewing all posts or a specific one
- Updating a post
- Deleting a post
Tools & Technologies
- Golang for writing backend logic.
- GORM ORM for interacting with a database (like PostgreSQL or SQLite).
- Gin web framework to create HTTP APIs.
- Postman to test your API.
- Heroku (or AWS) for deployment.
Step 1: Set Up Your Environment
1. Install Go
- Download from: https://golang.org/dl/
- Check version: go version
2. Create Your Project Directory
mkdir blog-api
cd blog-api
go mod init blog-api
Step 2: Install Required Packages
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite
Step 3: Project Structure
blog-api/
main.go
models/
post.go
controllers/
postController.go
database/
connection.go
Step 4: Define Your Model (models/post.go)
package models
import "gorm.io/gorm"
type Post struct {
gorm.Model
Title string `json:"title"`
Content string `json:"content"`
}
Step 5: Database Setup (database/connection.go)
package database
import (
"blog-api/models"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"log"
)
var DB *gorm.DB
func Connect() {
var err error
DB, err = gorm.Open(sqlite.Open("blog.db"), &gorm.Config{})
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
DB.AutoMigrate(&models.Post{})
}
Step 6: API Handlers (controllers/postController.go)
package controllers
import (
"blog-api/database"
"blog-api/models"
"net/http"
"github.com/gin-gonic/gin"
)
func GetPosts(c *gin.Context) {
var posts []models.Post
database.DB.Find(&posts)
c.JSON(http.StatusOK, posts)
}
func GetPostByID(c *gin.Context) {
var post models.Post
id := c.Param("id")
if err := database.DB.First(&post, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Post not found"})
return
}
c.JSON(http.StatusOK, post)
}
func CreatePost(c *gin.Context) {
var post models.Post
if err := c.BindJSON(&post); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
database.DB.Create(&post)
c.JSON(http.StatusCreated, post)
}
func UpdatePost(c *gin.Context) {
var post models.Post
id := c.Param("id")
if err := database.DB.First(&post, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Post not found"})
return
}
if err := c.BindJSON(&post); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
database.DB.Save(&post)
c.JSON(http.StatusOK, post)
}
func DeletePost(c *gin.Context) {
var post models.Post
id := c.Param("id")
if err := database.DB.First(&post, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Post not found"})
return
}
database.DB.Delete(&post)
c.JSON(http.StatusOK, gin.H{"message": "Post deleted"})
}
Step 7: Main Entry File (main.go)
package main
import (
"blog-api/controllers"
"blog-api/database"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
database.Connect()
r.GET("/posts", controllers.GetPosts)
r.GET("/posts/:id", controllers.GetPostByID)
r.POST("/posts", controllers.CreatePost)
r.PUT("/posts/:id", controllers.UpdatePost)
r.DELETE("/posts/:id", controllers.DeletePost)
r.Run() // Runs on localhost:8080
}
Step 8: Test in Postman
Start Server:
go run main.go
Endpoints to test:
- GET http://localhost:8080/posts
- POST http://localhost:8080/posts
- GET http://localhost:8080/posts/{id}
- PUT http://localhost:8080/posts/{id}
- DELETE http://localhost:8080/posts/{id}
Step 9: Deploy to Heroku
1. Install Heroku CLI
- https://devcenter.heroku.com/articles/heroku-cli
2. Initialize Git
git init
heroku login
heroku create
3. Add Procfile
web: ./main
4. Build Go Binary
go build -o main
5. Commit and Push
git add .
git commit -m "Initial commit"
git push heroku master
6. Open Live API
heroku open
Final Notes
- Add basic error handling
- Use environment variables for production DB
- Write a README file explaining your project