Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/omar-aldesi/go-ecommerce

Go Ecommerce API is a high-performance, scalable backend API built with Go, Gin, and Gorm. Designed for modern ecommerce applications, it features robust JWT authentication, custom error handling, and advanced product filtering. The project is fully containerized with Docker
https://github.com/omar-aldesi/go-ecommerce

docker ecommerce gin golang gorm postgresql rest-api

Last synced: about 1 month ago
JSON representation

Go Ecommerce API is a high-performance, scalable backend API built with Go, Gin, and Gorm. Designed for modern ecommerce applications, it features robust JWT authentication, custom error handling, and advanced product filtering. The project is fully containerized with Docker

Awesome Lists containing this project

README

        

# ๐Ÿ›’ Go Ecommerce API

[![Golang](https://img.shields.io/badge/Golang-00ADD8?style=for-the-badge&logo=go&logoColor=white)](https://golang.org/)
[![Gin](https://img.shields.io/badge/Gin-00ADD8?style=for-the-badge&logo=go&logoColor=white)](https://gin-gonic.com/)
[![Gorm](https://img.shields.io/badge/Gorm-29BEB0?style=for-the-badge&logo=go&logoColor=white)](https://gorm.io/)
[![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white)](https://www.docker.com/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white)](https://www.postgresql.org/)
[![Swagger](https://img.shields.io/badge/Swagger-85EA2D?style=for-the-badge&logo=swagger&logoColor=black)](https://swagger.io/)

Welcome to the Go Ecommerce API project! This repository contains a fully-functional RESTful API built using Go, Gin, and Gorm. The project leverages PostgreSQL as its database and includes full Docker integration for seamless development and deployment. Below you'll find all the information you need to clone, set up, and run this project, as well as an overview of its architecture and features.

๐ŸŽฏ Features

- Go Gin Gorm: A powerful combination for building RESTful APIs with performance and ease of use.

- JWT Authentication: Secure your API endpoints with JSON Web Tokens (JWT) for user authentication.

- Custom Error Handling: Robust error handling including validation and type-specific errors.

- Modern Project Structure: Clean and scalable code organization with clear separation between concerns.

- PostgreSQL Database: Reliable and scalable relational database integration using Gorm.

- Full Docker Integration: Effortless development and deployment with Docker, including Docker Compose.

- Advanced Currency Handling: Manage transactions and prices effectively with the gocurrency package.

- OpenAPI Documentation: Automatically generated API documentation for all endpoints.

- RESTful API Protocols: Adheres to REST principles for easy and predictable API interactions.

- Auth Middleware: Secure endpoints with a custom JWT-based authentication middleware.

- Token Blacklisting: Refresh token blacklisting for enhanced security.

- General Systems for Shipping & Payment: Modular and extensible design for handling shipping and payment logic.

- Advanced Product Filtering: Powerful and flexible filtering options for product listings.

๐Ÿ“ Project Structure

The project follows a modern Go project structure:

```bash
ecommerce/
โ”œโ”€โ”€ app/
โ”‚ โ”œโ”€โ”€ core/ # Core functionality like database and middleware
โ”‚ โ”œโ”€โ”€ models/ # Data models representing the database schema
โ”‚ โ”œโ”€โ”€ crud/ # CRUD operations on models
โ”‚ โ”œโ”€โ”€ schemas/ # Request/response schemas for API endpoints
โ”‚ โ”œโ”€โ”€ endpoints/ # API endpoints (organized by version)
โ”‚ โ””โ”€โ”€ middlewares/ # Custom middleware such as auth and error handling
โ”œโ”€โ”€ docs/ # OpenAPI documentation generated by Swaggo
โ”œโ”€โ”€ Dockerfile # Dockerfile for building the application
โ”œโ”€โ”€ docker-compose.yml # Docker Compose configuration for multi-service setup
โ”œโ”€โ”€ go.mod # Go module file
โ””โ”€โ”€ README.md # Project README file
```

๐Ÿ› ๏ธ Getting Started

Prerequisites

- Docker: Make sure you have Docker and Docker Compose installed on your machine.

- Go: Go should be installed if you want to run the application locally without Docker (optional).

๐Ÿš€ Cloning the Repository

To clone the repository, use the following command:

```bash
git clone https://github.com/omar-aldesi/go-ecommerce.git
cd ecommerce
```

๐Ÿณ Running the Application with Docker

The easiest way to run the project is using Docker and Docker Compose. This will automatically set up the application along with a PostgreSQL database.

Build and Run the Docker Containers:

```bash
docker-compose up --build
```

Access the Application:

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

Access Swagger UI:

The OpenAPI documentation will be accessible at http://localhost:8080/swagger/index.html.

โš™๏ธ Running the Application Locally

If you prefer to run the application locally without Docker:

Set Up PostgreSQL:

- Install PostgreSQL and create a database for the project.
- Update the database connection details in the environment variables.
- Install Dependencies:

```bash
go mod download
```

Run the Application:

```bash
go run main.go
```

Access the Application:

The API will be running at http://localhost:8080.

๐Ÿ›ก๏ธ Authentication
This API uses JWT tokens for authentication. Clients must include a valid JWT in the Authorization header for secured endpoints. The format should be:

```http
Authorization: Bearer
```

๐Ÿ”‘ JWT Token Management

Login: Clients can obtain a JWT by providing valid credentials via the /api/v1/auth/login endpoint.
Refresh Token: The application supports token refreshing and blacklisting, ensuring a secure token lifecycle.

๐Ÿงฉ API Documentation

The API documentation is generated using OpenAPI (Swagger) and is accessible at:

```bash
http://localhost:8080/swagger/index.html
```

This documentation provides detailed information about each endpoint, including request parameters, response formats, and authentication requirements.

โš ๏ธ Error Handling

The application has a custom error handling system that provides detailed and user-friendly error messages. Here are some examples:

Validation Error Handling
When a request fails validation, the system returns an error response with details about each invalid field:

```go
// ErrorResponse represents the structure of the error response
type ErrorResponse struct {
Errors map[string]interface{} `json:"errors"`
}

// HandleValidationErrors processes and returns validation errors
func HandleValidationErrors(c *gin.Context, err error) {
var ve validator.ValidationErrors
var je *json.UnmarshalTypeError

switch {
case errors.As(err, &ve):
errs := make(map[string]interface{})
for _, e := range ve {
errs[e.Field()] = formatErrorMessage(e)
}
c.JSON(400, ErrorResponse{Errors: errs})
case errors.As(err, &je):
errs := map[string]interface{}{
je.Field: fmt.Sprintf("Invalid value type. Expected %s", je.Type.String()),
}
c.JSON(400, ErrorResponse{Errors: errs})
default:
c.JSON(400, ErrorResponse{Errors: map[string]interface{}{"general": err.Error()}})
}
}

// formatErrorMessage formats a single validation error message
func formatErrorMessage(e validator.FieldError) string {
switch e.Tag() {
case "required":
return "This field is required"
case "email":
return "Invalid email address"
case "min":
if e.Type().Kind() == reflect.String {
return fmt.Sprintf("This field must be at least %s characters long", e.Param())
}
return fmt.Sprintf("This field must be at least %s", e.Param())
case "max":
if e.Type().Kind() == reflect.String {
return fmt.Sprintf("This field must be at most %s characters long", e.Param())
}
return fmt.Sprintf("This field must be at most %s", e.Param())
case "e164":
return "Invalid phone number format"
case "oneof":
return fmt.Sprintf("This field must be one of: %s", strings.Replace(e.Param(), " ", ", ", -1))
case "len":
return fmt.Sprintf("This field must be exactly %s characters long", e.Param())
case "numeric":
return "This field must contain only numeric characters"
case "alphanum":
return "This field must contain only alphanumeric characters"
default:
return fmt.Sprintf("Invalid value for %s", e.Field())
}
}
```

Custom HTTP Error Handling
You can use the HTTPError struct to return custom HTTP error responses:

```go
// HTTPError is a custom error type for HTTP errors
type HTTPError struct {
StatusCode int
Message string
}

func (e *HTTPError) Error() string {
return e.Message
}

func CustomErrorResponse(c *gin.Context, err error) {
var httpErr *HTTPError
if errors.As(err, &httpErr) {
c.JSON(httpErr.StatusCode, gin.H{"error": httpErr.Message})
}
log.Println("Error --> ", httpErr.StatusCode, err)
}
```
This allows for a consistent and clear error response structure across the application.

๐Ÿงช Testing
You can run unit and integration tests for the application using:

```bash
go test ./...
```

Make sure to configure the test database connection in your environment variables before running tests.

๐Ÿค Contributing
We welcome contributions! Please fork the repository and submit a pull request with your changes.

๐Ÿ“œ License
This project is licensed under the MIT License.