Skip to content

FrostByte0x/GDU-Go-Init

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GDU-Go-Init

A starter Go backend project demonstrating CRUD operations with authentication, file uploads, and security middleware. Built with Gin, GORM, and MariaDB.

Documentation generated by Claude.

Stack

  • Go with Gin — HTTP router
  • GORM — ORM for database access
  • MariaDB — relational database
  • JWT — authentication tokens
  • Swagger — auto-generated API documentation

Run with Docker Compose

1. Configure environment variables

Create a .env file at the project root:

JWT_SECRET=a-very-long-string-that-satisfies-256bits-requirements

The MariaDB credentials are set via mariadb.env (already included):

MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=mydb
MYSQL_USER=myuser
MYSQL_PASSWORD=mypassword

2. Start the database

docker-compose up -d

MariaDB runs on port 3306. The schema in init/001_schema.sql runs automatically on first start. Data is persisted in ./data/mysql/.

3. Run the server

go run main.go

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

Swagger UI is served at http://localhost:8080/swagger/index.html.


Run Tests

Tests use an in-memory SQLite database — no running database required.

go test ./tests/...

API Endpoints

All routes except /users/register and /users/login require a valid JWT token in the Authorization header:

Authorization: Bearer <token>

Auth

Method Endpoint Auth Description
POST /users/register No Create a new account
POST /users/login No Login and receive a JWT

Register

POST /users/register
{
  "email": "you@example.com",
  "password": "Secret123!"
}

Password requirements: minimum 8 characters, at least one uppercase letter, one lowercase letter, one digit, and one special character (! @ # % $ ^ & * .).

Login

POST /users/login
{
  "email": "you@example.com",
  "password": "Secret123!"
}

Returns a JWT token valid for 2 hours.


Projects

Method Endpoint Auth Description
GET /projects/ Yes List all projects
GET /projects/:id Yes Get one project
POST /projects/ Yes Create a project
PUT /projects/:id Yes Update a project
DELETE /projects/:id Yes Delete a project
PUT /projects/:id/like Yes Toggle like on a project

Create a project — supports optional image upload via multipart/form-data

POST /projects/
{
  "name": "My Project",
  "description": "A cool project",
  "skills": ["Go", "Docker", "SQL"]
}

Or with an image:

curl -X POST http://localhost:8080/projects/ \
  -H "Authorization: Bearer <token>" \
  -F "name=My Project" \
  -F "description=A cool project" \
  -F 'skills=["Go","Docker"]' \
  -F "image=@/path/to/image.png"

Uploaded images are automatically resized to 800px width (aspect ratio preserved) and saved to ./uploads/.

Update a project — partial update, only send fields you want to change

PUT /projects/1
{
  "name": "Updated name"
}

Toggle like — sends no body; adds the like if not present, removes it if already liked.


Comments

Method Endpoint Auth Description
POST /comments Yes Post a comment
POST /comments
{
  "project_id": 1,
  "content": "Great project!"
}

The user_id is set automatically from the JWT token — no need to send it in the body.


Project Structure

.
├── main.go                  # Entry point — wires middleware, routes, and database
├── go.mod                   # Module definition and dependencies
├── .env                     # JWT secret (not committed)
├── mariadb.env              # MariaDB credentials for Docker
├── docker-compose.yml       # MariaDB service
├── config/
│   ├── db.go                # GORM database connection
│   ├── cors.go              # CORS policy (localhost only)
│   ├── secure.go            # Security headers (XSS, CSP, frame denial)
│   └── rate_limit.go        # Global rate limiter (100 req/s)
├── models/
│   ├── user_model.go        # User schema with bcrypt password
│   ├── project_model.go     # Project schema with skills (JSON) and likes (M2M)
│   └── comment_model.go     # Comment schema linked to User and Project
├── controllers/
│   ├── user_controller.go   # Register, Login
│   ├── project_controller.go# CRUD + image upload + like toggle
│   └── comment_controller.go# Post comment
├── routes/
│   ├── user_routes.go       # /users group
│   ├── project_routes.go    # /projects group
│   └── comment_routes.go    # /comments group
├── middlewares/
│   └── auth.go              # JWT validation middleware
├── utils/
│   └── password_validator.go# Password strength rules
├── tests/
│   └── project_test.go      # Endpoint tests (SQLite in-memory)
├── docs/
│   ├── docs.go              # Generated Swagger spec
│   └── swagger.yaml         # OpenAPI definition
└── init/
    └── 001_schema.sql       # DB init script (runs on first Docker start)

Middleware

All routes pass through three global middleware layers applied at startup:

Middleware Details
Security Sets X-Frame-Options: DENY, X-XSS-Protection, and Content-Security-Policy: default-src 'self'
CORS Allows http://localhost with credentials; 12-hour preflight cache
Rate limiter 100 requests/second global limit; returns 429 on violation

Protected routes additionally run the JWT auth middleware, which reads the Authorization: Bearer <token> header, verifies the signature, and injects UserID into the request context.

About

Starter Project for the GDU - Go backend course. Simple CRUD operations with backend API using Gin and Gorm

Resources

Stars

Watchers

Forks

Contributors

Languages