Skip to content

ganfay/gin-content-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

54 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Gin Content API

A robust, production-ready RESTful API designed for content management, built with Go, Gin, and PostgreSQL.

πŸ“– Background:
This project was originally developed as a comprehensive implementation of the backend challenges from roadmap.sh, specifically combining concepts from the Blogging Platform API and Todo List API projects. It has since evolved into a well-structured boilerplate demonstrating modern Go practices.


✨ Key Features

  • Clean Architecture: Strict separation of concerns across handlers, repository, and models.
  • Advanced Security: bcrypt password hashing, JWT Access & Refresh token rotation, and strict resource ownership validation.
  • Robust Database: PostgreSQL integration using pgxpool for optimal connection pooling and /migrations for reliable schema management.
  • High Reliability: Includes comprehensive Integration Tests to ensure production readiness.
  • Developer Experience: Fully containerized with Docker, automated tasks via Makefile, and auto-generated Swagger OpenAPI docs.
  • Content Management: Full CRUD operations with pagination (limit/offset) and text search.

🧰 Tech Stack

Component Technology
Language Go (Golang)
Web Framework Gin
Database PostgreSQL
DB Driver pgxpool
Auth JWT (Access & Refresh) + bcrypt
Documentation Swagger (swaggo)
Infrastructure Docker & Docker Compose
Testing Go testing + Integration Tests

πŸ“‚ Project Structure

gin-content-api
β”‚
β”œβ”€β”€ auth/               # Authentication utilities
β”‚   β”œβ”€β”€ password.go     # Bcrypt password hashing and validation
β”‚   └── token.go        # JWT Access and Refresh token generation/parsing
β”‚
β”œβ”€β”€ db/                 # Database configuration
β”‚   └── database.go     # pgxpool connection initialization
β”‚
β”œβ”€β”€ docs/               # Auto-generated Swagger OpenAPI documentation
β”‚   β”œβ”€β”€ docs.go
β”‚   β”œβ”€β”€ swagger.json
β”‚   └── swagger.yaml
β”‚
β”œβ”€β”€ handlers/           # Controllers handling HTTP requests and responses
β”‚   β”œβ”€β”€ auth.go         # Login, Register, Refresh endpoints
β”‚   β”œβ”€β”€ me.go           # Get current authenticated user profile
β”‚   β”œβ”€β”€ ping.go         # Health check endpoint
β”‚   └── posts.go        # CRUD handlers for content
β”‚
β”œβ”€β”€ integration/        # E2E & Integration tests
β”‚   β”œβ”€β”€ setup_test.go   # Test DB setup and teardown logic
β”‚   └── ..._test.go     # API endpoint tests
β”‚
β”œβ”€β”€ migrations/         # SQL files for database schema migrations
β”‚   β”œβ”€β”€ 001_...sql      # Users table migration
β”‚   └── 002_...sql      # Posts table migration
β”‚
β”œβ”€β”€ models/             # Domain models and request/response structs
β”‚   β”œβ”€β”€ post.go         # Post structures
β”‚   └── user.go         # User structures
β”‚
β”œβ”€β”€ repository/         # Data access layer (PostgreSQL queries)
β”‚   β”œβ”€β”€ posts_repo.go   # Database operations for posts
β”‚   └── users_repo.go   # Database operations for users
β”‚
β”œβ”€β”€ router/             # Gin router configuration and middleware
β”‚   β”œβ”€β”€ middleware.go   # JWT validation middleware
β”‚   └── router.go       # API route registration
β”‚
β”œβ”€β”€ .env.example        # Example environment variables template
β”œβ”€β”€ .gitignore          # Git ignore rules
β”œβ”€β”€ docker-compose.yml  # Container orchestration (API + DB instances)
β”œβ”€β”€ Dockerfile          # Instructions to build the Go app container
β”œβ”€β”€ Makefile            # Automation commands (run, test, migrate)
└── main.go             # Entry point: wires up DB, repos, handlers, and starts server

πŸš€ Getting Started

1️⃣ Clone the Repository

First, clone the repository to your local machine:

git clone https://github.com/GanFay/gin-content-api.git
cd gin-content-api

🐳 2️⃣ Using Docker (Recommended)

The easiest way to get the API and the database running together is via Docker Compose.

# Start the application and database in the background
make dev
# OR
docker compose up --build -d
migrate -path migrations -database ${your_db_url} up
  • The API will be available at: http://localhost:8080
  • Swagger UI will be at: http://localhost:8080/swagger/index.html image

πŸ’» 3️⃣ Running Locally

If you prefer to run the Go app directly on your machine, you must set up the database manually.

  1. Start PostgreSQL: You can run just the database container or use a native local installation.
    docker-compose up -d postgres
    # OR locally run postgresql
  2. Install Dependencies:
    go mod tidy
  3. Environment Variables: Create a .env file in the root directory based on .env.example.
  4. Apply Migrations: Ensure your DB schema is up to date using the /migrations folder.
make migrations-up
# OR
migrate -path migrations -database ${your_db_url} up
  1. Run the Application:
    make run-app
    # OR
    go run main.go

πŸ§ͺ Running Tests

To execute all tests, ensure your database is running and execute:

go test ./... -v

βš™οΈ Environment Variables

Create a .env file in the root of your project:

# Full database connection string  
DB_URL=postgres://your_user:your_password@localhost:5432/your_db_name?sslmode=disable  
  
# JWT secrets for authentication (replace with secure random strings)  
JWT_SECRET_ACCESS=your_strongest_jwt_access_key  
JWT_SECRET_REFRESH=your_strongest_jwt_refresh_key  
  
# Individual database credentials (must match the values in DB_URL)  
PG_USER=your_user  
PG_PASSWORD=your_password  
PG_DB=your_db_name

πŸ“‘ API Endpoints

🌐 Public Endpoints

Method Endpoint Description
GET /ping Health check
POST /auth/register Register a new user
POST /auth/login Login user (returns Access & Refresh tokens)
GET /auth/refresh Refresh an expired access token(require a cookie token)

πŸ”’ Protected Endpoints (Requires JWT)

Header: Authorization: Bearer <access_token>

Method Endpoint Description
GET /users/me Get current authenticated user details
POST /auth/logout Logout user (invalidates refresh token)
POST /posts Create a new post
GET /posts Get all posts (supports limit and offset)
GET /posts/:id Get post by ID
PUT /posts/:id Update post (Author only)
DELETE /posts/:id Delete post (Author only)

πŸ”‘ Authentication Flow

  1. Login: Send POST /auth/login with email and password. The API returns an access_token and refresh_token.
  2. Access API: Attach Authorization: Bearer <access_token> to protected requests.
  3. Refresh: When the access_token expires, send a request to GET /auth/refresh using your refresh token to obtain a new pair.
  4. Logout: Send POST /auth/logout to securely revoke tokens.

πŸ“„ Pagination & Search

The /posts endpoint supports query parameters for pagination and filtering:

GET /posts?limit=10&offset=0&term=golang
Parameter Type Description
limit int Number of records to return (e.g., 10)
offset int Number of records to skip
term string Search posts by text (title/content)

πŸ—„ Database Schema

The schema is strictly managed via the /migrations directory.

users

Column Description
id Primary Key
username Unique username
email Unique email
password_hash Bcrypt hashed password
created_at Account creation timestamp

posts

Column Description
id Primary Key
author_id Foreign key referencing users(id)
title Post title
content Post body
category Category tag
tags Associated tags array
created_at Creation timestamp
updated_at Last update timestamp

πŸ“œ License

This project is licensed under the MIT License.

About

Go/Gin backend service demonstrating clean architecture. Built with PostgreSQL migrations, advanced JWT authentication, integration testing, and Docker.

localhost:8080/swagger/index.html

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages