Skip to content

About

Go (clean architecture inspired) RESTful API with crud operations, caching features, authentication and authorization mechanisms, and more. it uses Postgresql for storage, Redis for caching, swagger for documentation, etc...

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

72 Commits

Folders and files

Repository files navigation

Go Blog API

Go powered (clean architecture inspired) RESTful Blog API with crud operations, caching features, authentication and authorization mechanisms, and more. It uses Postgresql for storage, Redis for caching, Swagger for documentation, etc.

sections :


Features

  • Clean architecture inspired: this project's system design follows some basics principles (not all principles) of clean architecture to improve maintainability, make testing easier, increase flexibility and reusability, etc. (check System Architecture Diagram and Directory Layout sections below to see more details)
  • JWT based authentication (implemented here - used in AuthMiddleware and AuthService)
  • Hybrid RBAC-Ownership access control system (implemented in AccessControlMiddleware and used in routes).
    brief explanation:
    • Admin or Superuser: user with all accessibility and permissions (to manipulate everything)
    • Owner: only owner of each resource (posts, lists, comments, etc.) can manipulate (update or delete) that resource.
    • Viewer: viewers can only read other's resources.
  • Developed CLI tools to manage database migrations, server startup, etc. (powered by cobra) (implemented in cmd/commands/ - check Commands section below to see more details)
  • Implemented constructor based dependency injection (check at internal/dependencies and internal/http/dependencies.go)
  • Defined database schemas using raw SQL (check at migrations/) - see Database Entity-Relationship Diagram section below and review the Project's Database Design
  • Implemented repository pattern to organization CRUD operations, avoid tight coupling and simplify repository mocking in unit tests (check these: repo interface definitions / dependency injector / services / tests)
  • Implemented CRUD operations with standard and optimized database queries using raw SQL (check here)
  • Defined custom database errors to simplify handling Postgresql related errors and translating them for application services (check here)
  • Defined custom service errors to standardize application's error handling and generate proper message and code, to simplify making proper http-error-responses for Gin Handlers (here)
  • Implemented GENERIC based Handlers, Services, and Postgres Repositories, to centralize code logic as much as possible (by summarizing repetitive operations to one GENERIC all-inclusive function, and following DRY -don't repeat yourself- principle) (check them at: GENERIC_HANDLERS / GENERIC_SERVICES / BASE_REPOSITORY)
  • Designed StandardResponse to generate and send all successful/error responses in one standard way
  • Implemented Validation Error Translation to convert input (request data) validation errors to human readable messages
  • Designed and implemented Token Revocation strategy (backed by Redis) (implemented here - used in AuthService)
    • blacklist/revoke used but non-expired JWTs (until they expire)
    • blacklist-check for incoming JWTs (through cookie or Authorization header) to avoid abusing them
  • Implemented UserInfoCache (backed by Redis) : caching essential and commonly used user-information to make user related operations (authentication, access control check, user info fetching, etc.) faster (implemented here - used in AuthMiddleware and AuthService and UserService)
  • Included hashing features to improve security (like: PasswordHasher to store and verify hashed passwords instead of plain passwords, etc.)
  • Added Swagger documentation (see Swagger Docs Preview section below)
  • And more... (see below sections, and explore project's source code and discover other features!)

Directory Layout

Go-Blog-API
│
├── assets/
├── cmd/
│   ├── commands/
│   │   ├── rootCmd.go      # project's root command setup
│   │   ├── migrate.go      # implements migration related commands to work with db migrations
│   │   ├── serve.go        # implements `serve` command to init all dependencies and run server
│   │   └── superuser.go    # implements `create-superuser` & `delete-superuser` commands
│   └── main.go             # project entry point (setup above commands)
│
├── config/                 # load and initialize all project configurations
├── docs/                   # swagger documentation utilities
├── internal/
│   │
│   ├── application/  # [Business Logic Layer]
│   │   ├── service_errors/ # custom defined service error (standardize errors for response)
│   │   └── services/       # services (or usecases) implement business logic (layer
│   │                       # between handlers and concrete repositories)
│   │
│   ├── dependencies/       # dependency injectors (based on the defined contracts in domain)
│   │
│   ├── domain/       # [Domain Layer]
│   │   ├── entity/         # database entity definitions
│   │   ├── repository/     # repository interfaces to organize working with db entities
│   │   ├── pagination.go   # implements pagination logic for database queries
│   │   └── rules.go        # implements some rules for some entity fields
│   │
│   ├── http/         # [Delivery Layer]
│   │   ├── dto/            # DTOs to handle data flow (request validation & response construction)
│   │   ├── generics/       # generic type interfaces used in GENERIC Handlers and services
│   │   ├── handlers/       # endpoint handlers (bind requests, call services, serialize responses)
│   │   ├── helpers/        # helpers for generating standard responses, etc.
│   │   ├── middlewares/    # api endpoint middlewares
│   │   ├── validations/    # validation error handling + custom defined validations
│   │   ├── dependencies.go # DependencyContainer includes all api endpoint dependencies (all
│   │   │                   # repositories, services, handlers, infrastructure services, etc.)
│   │   ├── router.go       # api endpoints and routes
│   │   └── server.go       # main api server setup and initialization
│   │
│   └── infra         # [Infrastructure]
│       ├── database/
│       │   ├── postgres_repository/  # concrete repository (CRUD) implementation for all entities
│       │   ├── errors/               # database error handling + custom defined DB errors
│       │   └── database.go           # database (postgresql) connection setup
│       │
│       ├── redis/
│       │   ├── redis.go              # redis connection setup
│       │   ├── token_revocation.go   # blacklisting logic for used-JWTs to avoid abusing them
│       │   └── user_info.go          # caching essential and mainly used user information
│       │
│       └── security/
│           ├── hashing/    # hashing features to improve security (like: PasswordHasher, etc.)
│           └── jwt/        # jwt service implementation
│
├── migrations/             # database migrations (table and column definitions using raw SQL)
├── pkg/
│   ├── constants/          # includes commonly used keys as constants
│   └── logging/            # logger setup
├── tests/                  # ...
├── .gitignore
├── config.sample.yml
├── go.mod
├── go.sum
├── LICENSE
└── README.md

System Architecture Diagram

Domain Layer :

Includes pure business objects that encapsulate enterprise-business rules which are independent of any external frameworks or technologies. This layer is the most stable and least likely to change.

Service or Usecase Layer :

Contains application-specific business rules. it orchestrates the flow of data between delivery and domain layers, and represents the application's behavior and specific actions a user can take.

Infrastructure :

This layer is responsible for providing the infrastructure and external tools that other layers depend on; including database connection setup and concrete repository implementations (postgres repositories), redis connection setup, (third-party) security services, and more. Implementations in infrastructure satisfies the interfaces defined in the domain layer.

This separation makes it convenient to change any infrastructure implementation at any time.

Delivery or Presentation Layer :

It's the outermost layer of the system, and contains main application entry point. this layer is responsible for receiving external requests, calling service layer, and returning responses to the outside clients.

⚠️⚠️⚠️ Important Note:

the Dependency Rule of Clean Architecture: Source code dependencies can only point inward. An inner circle can know nothing about an outer circle.

This project's system design violates The Dependency Rule at one point. see application/ or [Business Logic Layer] in the Directory Structure section again and check its source code.

I use http Request DTOs directly in services, and return http Response DTOs directly from services; (in other words: application/service layer has one outward dependency and imports http layer DTOs) and this violates the Dependency Rule of Clean Architecture.

To fix that and follow Dependency Rule, I should:

  • Define dependent Input & Output DTOs in application or service layer
  • And define DTO Mappers to convert:
    • http Request DTOs to service Input DTOs
    • service Output DTOs to http Response DTOs

I think the decision in this situation is a tradeoff... defining dependent application layer DTOs and DTO Mappers adds 2 more steps to http handlers logic:

  • mapping http Request DTO to service Input DTO before calling related service
  • mapping service Output DTO to http Response DTO after getting related service's result

and I think these are 2 extra operations, and clutters the source code and increase performance cost. So in this situation, I preferred to violate the Dependency Rule on purpose, and keep system's performance more efficient, and the source code simpler... :)))


Database Entity-Relationship Diagram


Commands

here's a brief description for all of the project's CLI commands

  • serve: init and run the api server

    go run ./cmd serve
  • migrate: base command to handle database migrations

    • up: apply all or N up migrations

      flags:
      -s, --steps INT : number of steps for up migration (if not set: apply all up migrations)

      go run ./cmd migrate up # apply all up migrations
      go run ./cmd migrate up --steps 1 # apply 1 up migration
    • down: apply N down migrations

      flags:
      -s, --steps INT : number of steps for down migration (required)

      go run ./cmd migrate down --steps 1 # apply 1 down migration
      go run ./cmd migrate down --steps 2 # apply 2 down migration

      NOTE: you can't apply all down migrations at once, and -s or --steps flag is required for this command

    • force: set version V but don't run migration (ignores dirty state)

      go run ./cmd force 7 # set migration version to 7
      go run ./cmd force 4 # set migration version to 4
  • create-superuser: start an interactive prompt to create a superuser (a user with all accessibility and permissions)

    go run ./cmd create-superuser
  • delete-superuser: start an interactive prompt to delete a superuser

    go run ./cmd delete-superuser

Setup and Test

Docker Setup

Requirements: Docker

Guide for setting up the project using docker will be added soon!!!

Setup On Your Local

Requirements: Go - Postgresql - Redis

  • 1. Clone the repository:

    git clone https://github.com/hamidgh01/Go-Blog-API.git

    or download the zip file, and unzip

  • 2. Install dependencies:

    cd Go-Blog-API
    go mod tidy
  • 3. Set up your config file:

    Copy config.sample.yml to config.yml

    cp config.sample.yml config.yml

    and fill in the needed field properly (JWT, postgres, redis, etc.).

  • 4. Apply all database up migrations:

    go run ./cmd migrate up

    if migrations applied successfully, the result should be log messages like these:

    2026/06/20 20:35:43 direction: UP
    2026/06/20 20:35:43 all UP migrations applied successfully
    2026/06/20 20:35:43 current migration version: 8 (dirty: false)
    2026/06/20 20:35:43 migrate source and database closed
  • 5. Run the api server:

    go run ./cmd serve

Swagger Docs Preview

Access the API docs here: http://127.0.0.1:8000/api/swagger/index.html (change the host:port based on your configurations in config.yml)


License

This project is licensed under the MIT License. See the LICENSE File for more details.


Developed by hamidgh01

About

Go (clean architecture inspired) RESTful API with crud operations, caching features, authentication and authorization mechanisms, and more. it uses Postgresql for storage, Redis for caching, swagger for documentation, etc...

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages