Decorative Line

INDONESIA

3:05 AM, Cileungsi - Bogor

ARDHIDHANI

DEV

#2

Project

See All Projects

Sipencari Rest API

Project Sipencari : REST API

Published by Ardhi Ramadhani on August 3, 2023

Introduction

Sipencari is a forum discussion platform aimed at helping users find answers, connect with others, and share information efficiently. Built with Golang and the Echo framework, the platform provides a REST API backend with optimized performance, enhanced security, and scalability for handling forum discussions.

Link to the repository: sipencari-rest-api repository

Entity Relationship Diagram API Documentation in Swagger

Core Features

The Sipencari API provides a range of core features essential for a forum platform:

  • User Authentication: Uses JWT for secure token-based authentication and role-based authorization.
  • AWS Integration: Utilizes AWS S3 for media storage and the Google Maps API for geolocation features.
  • Database Management: PostgreSQL is used for stable and efficient data storage, with GORM managing database operations and automigrations.

Technical Stack

Programming Language: Golang
Framework: Echo
Database: PostgreSQL hosted on AWS RDS
Media Storage: AWS S3
Token Authentication: JWT for session management

ERD (Entity-Relationship Diagram)

The database structure for Sipencari is designed to manage discussions, user interactions, comments, and reactions effectively. Below is an ERD (Entity-Relationship Diagram) illustrating how the tables are related:

ERD for Sipencari

Key Tables

  1. users: Stores user information, including user_id, name, email, and password. Each user has roles and other details for profile customization.
  2. discussions: Manages discussion topics, with fields such as discussion_id, title, content, category, and view count. This table is key for forum topics.
  3. comments: Holds comments related to discussions, allowing users to respond to each topic.
  4. discussion_likes and comment_likes: These tables track likes on both discussions and comments, allowing users to show appreciation for content.
  5. comment_reactions: Tracks different reactions (like helpful marks) on comments, providing flexibility in user feedback.
  6. discussion_pictures and comment_pictures: Handle picture attachments associated with discussions and comments, enhancing the platform’s multimedia capabilities.
  7. discussion_locations: Provides location information for each discussion, which could be used for geotagging discussions or location-based filtering.

Relationships and Design Choices

Each table is linked through foreign keys, such as connecting comments to discussions and likes to users and discussions. Timestamps (created_at, updated_at, and deleted_at) across tables ensure that updates and deletions are tracked while enabling soft deletions for data recovery.

Project Structure

This project is structured for high maintainability with clear separation between various modules:

  1. Models: Defines the data structure for users, comments, and discussions, using GORM for ORM capabilities.
  2. Repositories: Handles CRUD (Create, Read, Update, Delete) operations with encapsulated database functions for data retrieval and manipulation.
  3. Services: Houses business logic, handling operations on data fetched from the repositories.
  4. Handlers: Manages HTTP requests, interacts with the services, and sends the appropriate responses to the client.
  5. Routes: Defines the API routes for user authentication, discussion management, and comments.

Database Schema

The database schema relies on relational tables with entities such as User, Discussion, and Comment. Here is an example of the User model struct:

type User struct {
    UserID    string    `json:"user_id" gorm:"size:225;primaryKey"`
    Name      string    `json:"name" gorm:"size:100"`
    Email     string    `json:"email" gorm:"size:255;unique"`
    Password  string    `json:"password" gorm:"size:255"`
    Picture   string    `json:"picture" gorm:"size:255"`
    Role      string    `json:"role" gorm:"size:10"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
    DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

Each model represents a table in PostgreSQL. The GORM ORM is configured to AutoMigrate models on startup, ensuring that database tables and relations are created if they don’t exist.

JWT Middleware

The API uses JWT (JSON Web Token) for session management and secure authentication. A custom middleware is set up to handle token creation and verification, helping protect routes by granting access only to authenticated users.

Here’s a sample configuration:

type ConfigJWT struct {
    SecretJWT      string
    ExpireDuration int
}
 
func (cj *ConfigJWT) Init() middleware.JWTConfig {
    return middleware.JWTConfig{
        Claims:     &JWTCustomClaims{},
        SigningKey: []byte(cj.SecretJWT),
    }
}
 
func (cj *ConfigJWT) GenerateToken(userID, role string) (string, error) {
    claims := JWTCustomClaims{
        ID:   userID,
        Role: role,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: time.Now().Local().Add(time.Hour * time.Duration(cj.ExpireDuration)).Unix(),
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    return token.SignedString([]byte(cj.SecretJWT))
}
 

The GenerateToken function produces a JWT containing user information, which is used to identify the user and enforce role-based access control throughout the application.

API Endpoints

The API uses modular routing, making it easy to manage and expand functionality. Key endpoints include:

  • /auth: Authentication routes for login and registration
  • /user: Manages user profile data
  • /discussions: CRUD operations for discussions
  • /comments: Comment management for discussions

Each endpoint is documented in Swagger, providing developers a clear interface for testing and understanding each endpoint’s requirements and responses.

Sample Endpoint Code

Below is a sample code snippet showing how endpoints are structured in main.go:

func main() {
    db := initialize.InitDB() // Initialize Database
    e := echo.New()
    routes.RouteRegister(e)
    if err := e.Start(":" + os.Getenv("PORT")); err != nil {
        e.Logger.Fatal("Shutting down server")
    }
}

This main function initializes the database, creates an Echo instance, registers routes, and then starts the server on the specified port.

AWS S3 for Media Storage

Media files, such as profile pictures and discussion images, are stored in AWS S3. This setup includes functions to upload single or multiple files, making it easy to manage media without worrying about server storage capacity.

func UploadToS3(c echo.Context, folder, filename string, src multipart.File) (string, error) {
    configS3 := &aws.Config{
        Region:      aws.String(os.Getenv("AWS_S3_REGION")),
        Credentials: credentials.NewStaticCredentials(os.Getenv("AWS_S3_BUCKET_KEY_ID"), os.Getenv("AWS_S3_BUCKET_SECRET_KEY"), ""),
    }
    s3Session := session.New(configS3)
    uploader := s3manager.NewUploader(s3Session)
 
    result, err := uploader.Upload(&s3manager.UploadInput{
        Bucket: aws.String(os.Getenv("AWS_S3_BUCKET_NAME")),
        Key:    aws.String(folder + filename),
        Body:   src,
    })
    if err != nil {
        return "", err
    }
    return result.Location, nil
}

The UploadToS3 function simplifies uploading media files to S3, storing them securely with unique identifiers to avoid naming conflicts.

Environment Configuration

Configurations are managed with environment variables set in a .env file. This includes:

  • Database credentials: DB_USERNAME, DB_PASSWORD, etc.
  • JWT settings: JWT_SECRET_KEY, JWT_COST, etc.
  • AWS S3 credentials: AWS_S3_BUCKET_KEY_ID, AWS_S3_BUCKET_SECRET_KEY, and AWS_S3_BUCKET_NAME

Using environment variables keeps sensitive information secure and allows for seamless transitions between development and production environments.

API Documentation

Swagger documentation is used to simplify API exploration and testing for developers. Here’s a preview:

Swagger Documentation for Sipencari

You can also view the full documentation on SwaggerHub.

Conclusion

The Sipencari REST API is a robust and scalable backend solution for forum discussion platforms. The API incorporates secure authentication, flexible routing, and efficient media management with AWS S3, providing a secure and user-friendly backend service for end users. With AWS integration, JWT-based authentication, and Echo's lightweight nature, Sipencari is well-suited for future growth and feature expansion.

Link to the repository: sipencari-rest-api repository


Decorative Line