Skip to content

This is an example project build using goserve with postgres support. It offers a performant and scalable framework, emphasizing feature separation, clean code, and testability. Ideal for REST API development, goserve simplifies unit and integration testing, ensuring high-quality, production-ready applications with ease.

License

Notifications You must be signed in to change notification settings

afteracademy/goserve-example-api-server-postgres

Docker Compose CI Architechture Starter Project Download

PostgreSQL API Server Example

Production-Ready Blog Service with GoServe Framework

Banner

A complete, production-ready REST API service built with GoServe framework, PostgreSQL, Redis, JWT authentication, and role-based authorization.

Documentation


GoServe Framework API Documentation Download Starter

Overview

This project is a fully production-ready blog service demonstrating best practices for building performant and secure backend REST API services with PostgreSQL. It showcases the application of the GoServe framework with clean architecture, feature separation, comprehensive testing, and production grade security.

Features

  • GoServe Framework - Built on the production-ready GoServe v2 framework
  • Clean Architecture - Well-structured, maintainable codebase with clear separation of concerns
  • PostgreSQL Integration - Full PostgreSQL support with migrations and type-safe queries
  • Redis Caching - High-performance caching layer for frequently accessed data
  • JWT Authentication - Secure token-based authentication with refresh tokens
  • Role-Based Authorization - Fine-grained access control with role management
  • API Key Support - Additional security layer for API access control
  • Request Validation - Comprehensive input validation using validator v10
  • Testing Suite - Extensive unit and integration test coverage
  • Docker Ready - Complete Docker Compose setup for easy deployment
  • Auto-Generated APIs - CLI tool for scaffolding new API endpoints
  • Type-Safe DTOs - Structured data transfer objects for all requests/responses

Technology Stack

Quick Start

Prerequisites

Installation

1. Clone the Repository

git clone https://github.com/afteracademy/goserve-example-api-server-postgres.git
cd goserve-example-api-server-postgres

2. Generate RSA Keys

go run .tools/rsa/keygen.go

3. Create Environment Files

go run .tools/copy/envs.go 

4. Start with Docker Compose

docker compose up --build

The API server will be available at: http://localhost:8080

5. Health Check

docker inspect --format='{{.State.Health.Status}}' goserver-postgres

6. Run Tests

docker exec -t goserver-postgres go test -v ./...

Troubleshooting

If you encounter issues:

  • Ensure port 8080 is available (change SERVER_PORT in .env if needed)
  • Ensure port 5432 is available (change DB_PORT in .env if needed)
  • Ensure port 6379 is available (change REDIS_PORT in .env if needed)

Local Development

For local development without Docker:

go mod tidy

Keep Docker containers for postgres and redis running, but stop the goserver-postgres container.

Update the following in .env and .test.env:

DB_HOST=localhost
REDIS_HOST=localhost

Run the application:

go run cmd/main.go

Or use VS Code: Use the Run and Debug panel for an enhanced development experience.

Architecture

Design Principles

The architecture is designed to make each API independent while sharing services among them. This promotes:

  • Code Reusability - Shared services across multiple endpoints
  • Team Collaboration - Reduced conflicts when working in teams
  • Feature Isolation - Easier testing and maintenance

Request Flow

Request-Response-Design

Startup Flow:
cmd/mainstartup/servermodule, postgres, redis, routerapi/[feature]/middlewaresapi/[feature]/controllerapi/[feature]/serviceauthentication, authorizationhandlersresponse

API Structure

Sample API
├── dto/
│   └── create_sample.go     # Data Transfer Objects
├── model/
│   └── sample.go            # PostgreSQL Table Model
├── middleware/              # (Optional) Feature-specific middleware
│   └── custom.go
├── controller.go            # Route definitions & handlers
└── service.go              # Business logic & data operations

Key Components:

  • DTOs - Request/response body definitions in dto/ directory
  • Models - PostgreSQL table models in model/ directory
  • Controller - Defines endpoints and handles HTTP requests
  • Service - Contains business logic and data operations
  • Middleware - Authentication, authorization, and custom middleware

Project Structure

Directory Purpose
api/ Feature-based API implementations
cmd/ Application entry point (main.go)
common/ Shared code across all APIs
config/ Environment variable configuration
keys/ RSA keys for JWT token signing
migrations/ PostgreSQL database migration files
startup/ Server initialization, DB, Redis, routing
tests/ Integration test suites
utils/ Utility functions

Helper Directories:

  • .extra/ - PostgreSQL initialization scripts, assets, documentation
  • .github/ - CI/CD workflows
  • .tools/ - Code generators, key generation utilities
  • .vscode/ - Editor configuration and debug settings

Generate New APIs

Scaffold a new API endpoint with a single command:

go run .tools/apigen.go sample

This creates the complete structure under api/sample/ with:

  • Model definitions
  • DTO templates
  • Controller skeleton
  • Service interface

API Documentation

API Documentation

Complete API documentation with request/response examples and authentication details

Code Examples

Model

api/sample/model/sample.go

package model

import (
	"time"

	"github.com/google/uuid"
)

type Sample struct {
	ID				uuid.UUID	// id
	Field 		string		// field
	Status		bool			// status
	CreatedAt time.Time	// created_at
	UpdatedAt time.Time	// updated_at
}

DTO

api/sample/dto/create_sample.go

package dto

import (
	"time"

	"github.com/google/uuid"
)

type InfoSample struct {
	ID				uuid.UUID `json:"_id" binding:"required"`
	Field 		string 		`json:"field" binding:"required"`
	CreatedAt time.Time `json:"createdAt" binding:"required"`
}

Service

api/sample/service.go

package sample

import (
	"context"

	"github.com/afteracademy/goserve-example-api-server-postgres/api/sample/dto"
	"github.com/afteracademy/goserve-example-api-server-postgres/api/sample/model"
	"github.com/afteracademy/goserve/v2/redis"
	"github.com/afteracademy/goserve/v2/postgres"
	"github.com/google/uuid"
)

type Service interface {
	FindSample(id uuid.UUID) (*model.Sample, error)
}

type service struct {
	db							postgres.Database
	infoSampleCache	redis.Cache[dto.InfoSample]
}

func NewService(db postgres.Database, store redis.Store) Service {
	return &service{
		db:								db,
		infoSampleCache:	redis.NewCache[dto.InfoSample](store),
	}
}

func (s *service) FindSample(id uuid.UUID) (*model.Sample, error) {
	ctx := context.Background()

	query := `
		SELECT
			id,
			field,
			status,
			created_at,
			updated_at
		FROM samples
		WHERE id = $1
	`

	var m model.Sample

	err := s.db.QueryRow(ctx, query, id).
		Scan(
			&m.ID,
			&m.Field,
			&m.Status,
			&m.CreatedAt,
			&m.UpdatedAt,
		)

	if err != nil {
		return nil, err
	}

	return &m, nil
}

Notes: The Service embeds the interface

github.com/afteracademy/goserve/v2/network/interfaces.go

type BaseService interface {
	Context() context.Context
}
  • Redis Cache: redis.Cache[dto.InfoSample] provide the methods to make common redis queries for the DTO dto.InfoSample

Controller

api/sample/controller.go

package sample

import (
	"github.com/afteracademy/goserve-example-api-server-postgres/api/sample/dto"
	"github.com/afteracademy/goserve-example-api-server-postgres/common"
	coredto "github.com/afteracademy/goserve/v2/dto"
	"github.com/afteracademy/goserve/v2/network"
	"github.com/afteracademy/goserve/v2/utility"
	"github.com/gin-gonic/gin"
)

type controller struct {
	network.Controller
	common.ContextPayload
	service Service
}

func NewController(
	authMFunc network.AuthenticationProvider,
	authorizeMFunc network.AuthorizationProvider,
	service Service,
) network.Controller {
	return &controller{
		Controller: 		network.NewController("/sample", authMFunc, authorizeMFunc),
		ContextPayload: common.NewContextPayload(),
		service:				service,
	}
}

func (c *controller) MountRoutes(group *gin.RouterGroup) {
	group.GET("/id/:id", c.getSampleHandler)
}

func (c *controller) getSampleHandler(ctx *gin.Context) {
	uuidParam, err := network.ReqParams[coredto.UUID](ctx)
	if err != nil {
		c.Send(ctx).BadRequestError(err.Error(), err)
		return
	}

	sample, err := c.service.FindSample(uuidParam.ID)
	if err != nil {
		c.Send(ctx).NotFoundError("sample not found", err)
		return
	}

	data, err := utility.MapTo[dto.InfoSample](sample)
	if err != nil {
		c.Send(ctx).InternalServerError("something went wrong", err)
		return
	}

	c.Send(ctx).SuccessDataResponse("success", data)
}

Controller Interface: Implements github.com/afteracademy/goserve/v2/network.Controller

type Controller interface {
	BaseController
	MountRoutes(group *gin.RouterGroup)
}

type BaseController interface {
	ResponseSender
	Path() string
	Authentication() gin.HandlerFunc
	Authorization(role string) gin.HandlerFunc
}

Register Controller

startup/module.go

import (
	...
	"github.com/afteracademy/goserve-example-api-server-postgres/api/sample"
)

...

func (m *module) Controllers() []network.Controller {
	return []network.Controller{
		...
		sample.NewController(m.AuthenticationProvider(), m.AuthorizationProvider(), sample.NewService(m.DB, m.Store)),
	}
}

Related Projects

Explore other GoServe example implementations:

  1. GoServe Framework
    Core framework with PostgreSQL, MongoDB, Redis, and NATS support

  2. MongoDB API Server
    Complete REST API with MongoDB and clean architecture

  3. Microservices Example
    NATS-based microservices communication patterns

Generate Starter Project

Use the GoServeGen CLI to generate a starter project:

# Install GoServeGen CLI
go install github.com/afteracademy/goservegen@latest

# Generate a new project
goservegen create my-project --db=postgres

Or download the starter project directly:

Articles & Tutorials

Contributing

We welcome contributions! Please feel free to:

  • Fork the repository
  • Open issues for bugs or feature requests
  • Submit pull requests with improvements
  • Share your feedback and suggestions

Learn More

Subscribe to AfterAcademy on YouTube for in-depth tutorials and concept explanations:

YouTube

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support This Project

If you find this project useful, please consider:

  • Starring ⭐ this repository
  • Sharing with the community
  • Contributing improvements
  • Reporting bugs and issues

About

This is an example project build using goserve with postgres support. It offers a performant and scalable framework, emphasizing feature separation, clean code, and testability. Ideal for REST API development, goserve simplifies unit and integration testing, ensuring high-quality, production-ready applications with ease.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages