Skip to content

usman250994/go-serverless-microservices

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ—οΈ Go Serverless Microservices

Work in Progress

Go Version License Build Status Architecture

Scalable, maintainable, and production-ready microservices in Go, powered by Clean Architecture & DDD.


✨ Key Features

  • 🧹 Clean Architecture: Handlers β†’ Services β†’ Models
  • πŸ›οΈ Domain-Driven Design (DDD): Modular, business-focused code
  • πŸ“¦ Scalable Structure: Add new domains/services with zero coupling
  • πŸ”Œ Flexible Integration: REST, gRPC, GraphQL ready
  • πŸ§ͺ Testable Services: Clear boundaries for easy testing
  • ⚑ Minimal Boilerplate: Production-ready from the start

πŸ—ΊοΈ Architecture Overview

flowchart TD
  %% --- AWS Services Layer ---
  subgraph AWS["AWS Managed Services"]
    Cognito["Cognito (User Authentication)"]
    APIGW["API Gateway (Entry Point)"]
  end

  %% --- Lambda Layer ---
  subgraph Lambda["AWS Lambda (Custom Code)"]
    Route["Route"]
    Handler["Handler"]
    Validator["Validation"]
    Service["Service Layer"]
    Repo["Repository Layer"]
  end

  %% --- Databases ---
  DynamoDB[("DynamoDB")]
  OpenSearchDB[("OpenSearch DB")]

  %% --- Client/User ---
  User["User / Client"]

  %% --- Flows ---
  User -->|Sign in| Cognito
  User -->|API call with JWT in header| APIGW
  APIGW -->|Invoke Lambda for Users Service| Route
  APIGW -->|Invoke Lambda for Items Service| Route

  %% Inside Lambda execution path
  Route --> Handler
  Handler --> Validator
  Validator --> Service
  Service --> Repo

  %% Repos to DBs
  Repo --> DynamoDB
  Repo --> OpenSearchDB
Loading

How it works:

  • Users authenticate with Cognito and receive a JWT token.
  • API requests include the JWT in the Authorization header.
  • API Gateway forwards requests to the appropriate Lambda (users/items).
  • Each Lambda's main.go calls the internal route, which calls the handler.
  • The handler validates/authenticates the JWT, then calls the service layer for business logic.
  • The service layer calls the repo layer for DB operations (DynamoDB for users, OpenSearch for items).

πŸ“‚ Project Structure

cmd/
 └── users/
   └── main.go        # Entry point for Users microservice
internal/
 └── users/
   β”œβ”€β”€ routes.go      # Routes & handler mapping
   β”œβ”€β”€ handler.go     # HTTP handlers
   β”œβ”€β”€ service.go     # Business logic
   └── model.go       # Domain models/entities
   └── repo.go        # crud operations for db
   └── type.go        # request response types for validation

πŸš€ How It Works

  • main.go: Lambda entry point, loads config, sets up router, and starts the service.
  • routes.go: Registers endpoints and maps them to handlers.
  • handler.go: Processes requests, extracts and validates JWT from headers, and calls the service layer.
  • type.go: Contains request/response DTOs for validation.
  • service.go: Contains business logic and orchestrates workflows.
  • model.go: Defines domain entities and data structures.
  • repo.go: Handles DB operations (DynamoDB for users, OpenSearch for items).


πŸ› οΈ Tech Stack

  • Language: Go (Golang)
  • Cloud: AWS (tested with Cognito, Api gateway and lambdas)
  • Architecture: Clean Architecture + DDD
  • Routing: chi
  • Persistence: Extendable (DynamoDB)
  • Validation: go-playground/validator
  • Authentication: using jwt for extracting userId

🧭 Principles

  • βœ… Single Responsibility: Each layer does one job
  • βœ… Dependency Inversion: Inner layers never depend on outer
  • βœ… Explicit Boundaries: Clear contracts between layers
  • βœ… Scalability: Easily add new domains

πŸš€ Getting Started

1. Prerequisites

2. Set Up AWS Services

  • Cognito: Create a User Pool and an App Client (enable USER_PASSWORD_AUTH). Quickstart Guide
    • Add a test user via AWS Console or CLI.
    • Use the AWS Console or AdminCreateUser CLI.
    • Get a JWT token for your test user:
      curl -X POST -H "Content-Type: application/x-amz-json-1.1" \
        -H "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth" \
        -d '{"AuthParameters": {"USERNAME": "<your_email>", "PASSWORD": "<your_password>"}, "AuthFlow": "USER_PASSWORD_AUTH", "ClientId": "<your_cognito_app_client_id>"}' \
        https://cognito-idp.<region>.amazonaws.com/
      • Copy the IdToken from the response and use it as your JWT in API requests.
  • DynamoDB: Create a Table (e.g., users).
  • Lambda: Deploy your Go binary as a Lambda function if you want to run on AWS. You can also run locally with go run ./cmd/users/main.go for quick testing and development.
  • OpenSearch (optional, for items service): Create a domain and index. Warning: OpenSearch can incur significant costs if not managed carefully. Use the free tier or development domains for testing.

Note: You do NOT need to set up API Gateway to test locally or to deploy your Lambda if you are invoking it directly or using the AWS Lambda console. API Gateway is only needed if you want to expose your Lambda as a public HTTP endpoint.

3. Configure Environment Variables

Create a .env file in your project root with:

AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=your-region
USERS_TABLE=users
LOCAL=true
OPEN_SEARCH_END_POINT=https://your-opensearch-endpoint
OPEN_SEARCH_INDEX=your-index

⚠️ Warning: Never commit your .env file or secrets to version control.

4. Run Locally

# Clone repo
git clone https://github.com/usman250994/go-serverless-microservices.git

# Run users service locally
cd cmd/users
go run main.go

# Run items service locally (requires OpenSearch setup)
cd ../items
go run main.go

πŸ§ͺ Test Your API (Postman or curl)

  1. Get a JWT token (see Cognito curl above).

  2. Call the test endpoint:

    POST http://localhost:8080/user

    Headers:

    • Authorization: Bearer <your_id_token>
    • Content-Type: application/json

    Body (JSON):

    {
      "name": "john",
      "email": "doe@gmail.com",
      "ratings": 25.0,
      "userType": "renter"
    }

    πŸ§‘β€πŸ’» This is a test API in this boilerplate. Fork and extend for your own product!

6. Deploy to AWS Lambda

  • Build your Go binary for Linux:
    GOOS=linux GOARCH=amd64 go build -o main ./cmd/users/main.go
    zip deployment.zip main
    # Upload deployment.zip to Lambda via AWS Console or CLI
  • Set environment variables in the Lambda console to match your .env file.
  • Connect your Lambda to API Gateway for public access.

⚠️ OpenSearch Cost Warning

OpenSearch can incur significant costs if not managed carefully.

  • Use the free tier or development domains for testing.
  • Delete unused domains promptly.
  • Monitor your AWS billing dashboard regularly.

🚧 Upcoming Features

  • πŸ—„οΈ Database Abstraction: Internal package for DynamoDB accessβ€”cleaner, decoupled repo logic.
  • πŸ“‘ Event Streaming: Integrate AWS SNS, SQS, and DynamoDB Streams for real-time event sourcing.
  • πŸ” Query Wrapper: Generic query builder to simplify and standardize DynamoDB queries.

🀝 Contributing

Contributions are welcome! Open issues or PRs to improve structure or add features.


πŸ“œ License

MIT License – use this boilerplate for your own projects.

Medium arcticle

go serverless microservices boiler plate

About

A production-ready Go boilerplate for building scalable serverless microservices on AWS. Features Clean Architecture, modular domain-driven design, JWT authentication, DynamoDB and OpenSearch integration, and easy local or Lambda deployment. Perfect for rapid prototyping and extensible for real-world products.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages