A modern, high-performance social media API built with Go, featuring real-time capabilities and a RESTful architecture.
-
Core Infrastructure
- Health Check Endpoint
- Chi Router with context middleware
- Environment-based configuration
- Structured logging with request IDs
- Database migrations with versioning
- Multi-layer Validation with
go-playground/validator - Database Search Optimization (pg_trgm extension and GIN indexes)
-
API Features
- RESTful JSON API with consistent response format
- Post Management (CRUD operations)
- User Profiles with follow/unfollow functionality
- Comment System with nested comments
- Personalized User Feed with metadata
- Optimized search across posts and users
- Context-aware request handling
- Structured error responses with HTTP status codes
- Input validation at multiple layers
- Partial updates with PATCH
- Optimistic Concurrency Control
-
Architecture
- Clean Repository Pattern implementation
- Database optimization with GIN indexes
- Efficient query patterns and joins
- User authentication & authorization (JWT)
- User registration & login
- Like/Unlike functionality
- Real-time notifications
- Rate limiting
- Redis caching
- Advanced search filters
- File upload (images/videos)
- Docker support
- Go 1.21 or higher
- PostgreSQL 13+
- Git for version control
- Air (optional, for live reload during development)
- Golang Migrate (for database migrations)
-
Clone the repository
git clone https://github.com/nati3514/Social.git cd Social -
Install dependencies
go mod download
-
Configure environment
- Copy
.env.exampleto.env - Update database credentials and settings
cp .env.example .env # Edit .env with your configuration - Copy
-
Run the application
# Using Go directly go run ./cmd/api # Or with Air for live reload go install github.com/cosmtrek/air@latest air
The API will be available at
http://localhost:8080
Social/
βββ cmd/
β βββ api/ # API server
β β βββ main.go # Application entry point
β β βββ api.go # Server setup and routing
β β βββ health.go # Health check handler
β βββ migrate/ # Database migration and seeding
βββ internal/
β βββ db/ # Database connection and setup
β βββ env/ # Environment variable helpers
β βββ store/ # Repository pattern implementation
β βββ postgres/ # PostgreSQL implementations
β βββ store.go # Store interfaces
βββ migrations/ # Database migration files
βββ .env.example # Example environment variables
βββ README.md # This file
Interactive API documentation is available using Swagger UI:
http://localhost:8080/swagger/index.html
POST /v1/login- Authenticate and get JWT tokenPOST /v1/register- Create a new user account
| Method | Endpoint | Description |
|---|---|---|
GET |
/v1/posts |
List all posts with pagination |
POST |
/v1/posts |
Create a new post |
GET |
/v1/posts/{id} |
Get a specific post with comments |
PATCH |
/v1/posts/{id} |
Partially update a post |
DELETE |
/v1/posts/{id} |
Delete a post |
| Method | Endpoint | Description |
|---|---|---|
GET |
/v1/users/feed |
Get user's personalized feed |
| Method | Endpoint | Description |
|---|---|---|
GET |
/v1/users/{userID} |
Get user profile |
PUT |
/v1/users/{userID}/follow |
Follow a user |
PUT |
/v1/users/{userID}/unfollow |
Unfollow a user |
| Method | Endpoint | Description |
|---|---|---|
GET |
/v1/health |
Health check |
curl -X POST http://localhost:8080/v1/posts \
-H "Content-Type: application/json" \
-d '{"title":"First Post","content":"This is my first post","user_id":1}'curl "http://localhost:8080/v1/users/feed?limit=10&offset=0&sort=desc"{
"data": {},
"meta": {
"total": 0,
"page": 1,
"limit": 20
}
}{
"error": {
"message": "Resource not found",
"code": 404
}
}| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 20 | Items per page (max 100) |
offset |
integer | 0 | Items to skip |
sort |
string | "desc" | Sort order ("asc" or "desc") |
since |
string | - | Filter posts after timestamp |
until |
string | - | Filter posts before timestamp |
tags |
string | - | Comma-separated tags |
search |
string | - | Search in post content |
Use the migration script to manage database schema:
# Windows
.\migrate.ps1 up
# Linux/macOS
migrate -path ./migrations -database "postgres://user:pass@localhost:5432/dbname?sslmode=disable" upAPI documentation is automatically generated using swag:
# Install swag
go install github.com/swaggo/swag/cmd/swag@latest
# Generate docs
swag init -g cmd/api/main.goThis project is licensed under the MIT License - see the LICENSE file for details.
-
Create a new PostgreSQL database
-
Run migrations:
# Windows .\migrate.ps1 up # Linux/macOS migrate -path ./migrations -database "postgres://user:pass@localhost:5432/dbname?sslmode=disable" up
-
(Optional) Seed with test data:
.\migrate.ps1 seed
API documentation is automatically generated using swag:
# Install swag if not already installed
go install github.com/swaggo/swag/cmd/swag@latest
# Generate docs
swag init -g cmd/api/main.go -o docs-
Create a new handler function with Swagger annotations:
// @Summary Create a new post // @Description Create a new blog post // @Tags posts // @Accept json // @Produce json // @Param post body CreatePostRequest true "Post data" // @Success 201 {object} Post // @Router /v1/posts [post] func (h *PostHandler) Create(w http.ResponseWriter, r *http.Request) { // Handler implementation }
-
Regenerate the documentation:
.\migrate.ps1 gen-docs
go test -v ./...This project is licensed under the MIT License - see the LICENSE file for details.
# Get user by ID
curl http://localhost:8080/v1/users/1
# Follow a user
curl -X PUT http://localhost:8080/v1/users/2/follow \
-H "Content-Type: application/json" \
-d '{"user_id": 1}'
# Unfollow a user
curl -X PUT http://localhost:8080/v1/users/2/unfollow \
-H "Content-Type: application/json" \
-d '{"user_id": 1}'
# Successful response (204 No Content for follow/unfollow)
# No content in response body
# Error responses:
# Already following (409 Conflict)
{
"error": "record already exists"
}
# User not found (404 Not Found)
{
"error": "record not found"
}
# Get user profile response (200 OK)
{
"data": {
"id": 1,
"name": "Nati Age",
"email": "nati@example.com",
"created_at": "2023-10-31T10:00:00Z"
}
}The API implements optimistic concurrency control to handle concurrent updates to resources. When updating a post, include the current version number in the request. If the version on the server doesn't match the provided version, the update will be rejected with a 409 Conflict status code.
- Each post has a version number that increments with each update
- When updating a post, include the current version in the request
- The server verifies the version matches before applying updates
- If versions don't match, a 409 Conflict is returned
{
"error": "edit conflict: post has been modified by another user"
}The application includes a database seeding system to generate test data for development and testing. The seeder creates realistic-looking users, posts, and comments with varied content.
.\migrate.ps1 seedmake seed- Creates 100 random users with realistic names and email addresses
- Generates 20 posts with varied content and tags
- Creates 20 comments on random posts
- Includes proper error handling and logging
Seeding database...
2025/10/30 17:12:57 Database seeded successfully# Create a new migration
.\migrate.ps1 create migration_name
# Apply all migrations
.\migrate.ps1 up all
# Rollback last migration
.\migrate.ps1 down 1
# Check migration status
.\migrate.ps1 version
# Seed the database with test data
.\migrate.ps1 seed# Install migrate
brew install golang-migrate
# Create a new migration
migrate create -ext sql -dir cmd/migrate/migrations -seq migration_name
# Apply all migrations
migrate -path=cmd/migrate/migrations -database "postgres://user:password@localhost:5432/dbname?sslmode=disable" up
# Rollback last migration
migrate -path=cmd/migrate/migrations -database "postgres://user:password@localhost:5432/dbname?sslmode=disable" down 1
# Seed the database with test data
make seedAir automatically reloads the application when you make changes to .go files:
airConfiguration is in .air.toml.
| Variable | Description | Default |
|---|---|---|
ADDR |
Server address and port | :8080 |
DB_HOST |
Database host | localhost |
DB_PORT |
Database port | 5432 |
DB_USER |
Database user | postgres |
DB_PASSWORD |
Database password | - |
DB_NAME |
Database name | social |
DB_SSLMODE |
SSL mode for database | disable |
DB_MAX_OPEN_CONNS |
Max open connections | 25 |
DB_MAX_IDLE_CONNS |
Max idle connections | 25 |
DB_MAX_IDLE_TIME |
Max connection idle time | 15m |
This project follows Conventional Commits for commit messages:
feat:- New featuresfix:- Bug fixesdocs:- Documentation changesrefactor:- Code refactoringperf:- Performance improvementstest:- Test additions/changeschore:- Maintenance tasks
- Handler Layer: HTTP request/response handling, input validation
- Service Layer: Business logic, data validation
- Store Layer: Database operations, data integrity
- Middleware: Cross-cutting concerns (logging, auth, context management)
- Consistent error responses with appropriate HTTP status codes
- Detailed error messages in development
- Secure error messages in production
- Structured error logging
Example commits:
feat(auth): add JWT authentication
fix(api): resolve health check timeout
docs: update API endpoint documentation- Go - Programming language
- Chi - HTTP router
- godotenv - Environment variable management
- Air - Live reload for development
- validator - Request payload validation
This project is licensed under the MIT License - see the LICENSE file for details.
Natnael - @nati3514
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feat/amazing-feature) - Commit your changes using conventional commits (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
- Project setup
- Health check endpoint
- Environment configuration
- Database setup (PostgreSQL)
- User authentication
- User registration
- User login
- User profiles
- Password reset
- Posts (CRUD)
- Comments
- Likes
- Follow system
- Feed algorithm
- Search
- Notifications
- File uploads
- Caching (Redis)
- Rate limiting
- API documentation (Swagger)
- Docker containerization
For questions or issues, please open an issue on GitHub.
β Star this repository if you find it helpful!