Skip to content

architxkumar/Blogging-Platform-API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Blogging Platform API

A simple RESTful API with basic CRUD operations for a personal blogging platform built with Go, Gorilla Mux, and PostgreSQL.

Built as a learning project for Backend Roadmap on roadmap.sh.

Table of Contents

Features

  • ✅ Create new blog posts
  • ✅ Update existing blog posts
  • ✅ Delete blog posts
  • ✅ Retrieve a single blog post by ID
  • ✅ Retrieve all blog posts
  • ✅ Search blog posts by term (searches in title, content, and category)
  • ✅ Request ID tracking for debugging
  • ✅ Comprehensive logging middleware
  • ✅ Input validation with proper error responses

Tech Stack

  • Language: Go 1.24
  • Web Framework: Gorilla Mux
  • Database: PostgreSQL
  • Environment Management: godotenv
  • Database Driver: lib/pq

Prerequisites

  • Go 1.24 or higher
  • PostgreSQL 12 or higher
  • Git

Getting Started - Local Development Setup

Follow these steps to set up the project on your local machine:

Step 1: Install Prerequisites

Install Go

  • macOS:
    brew install go
  • Linux (Ubuntu/Debian):
    sudo apt update
    sudo apt install golang-go
  • Windows: Download and install from golang.org/dl

Verify installation:

go version

Install PostgreSQL

  • macOS:
    brew install postgresql@15
    brew services start postgresql@15
  • Linux (Ubuntu/Debian):
    sudo apt update
    sudo apt install postgresql postgresql-contrib
    sudo systemctl start postgresql
    sudo systemctl enable postgresql
  • Windows: Download and install from postgresql.org/download

Verify installation:

psql --version

Step 2: Clone the Repository

git clone https://github.com/architxkumar/Blogging-Platform-API.git
cd Blogging-Platform-API

Step 3: Install Go Dependencies

go mod download

Step 4: Set Up PostgreSQL Database

  1. Create a PostgreSQL user (if needed):

    # On macOS/Linux, switch to postgres user
    sudo -u postgres psql
    
    # Or connect directly
    psql postgres

    Inside PostgreSQL prompt:

    CREATE USER your_username WITH PASSWORD 'your_password';
    ALTER USER your_username CREATEDB;
    \q
  2. Create the database:

    # Connect to PostgreSQL
    psql -U your_username -d postgres

    Inside PostgreSQL prompt:

    CREATE DATABASE blogs;
    \q
  3. Run the schema to create tables:

    psql -U your_username -d blogs -f internal/db/schema.sql
  4. (Optional) Load sample data for testing:

    psql -U your_username -d blogs -f internal/db/sample_posts_insert.sql

Step 5: Configure Environment Variables

Create a .env.development file in the root directory of the project:

# Create the file
touch .env.development

Add the following configuration (update with your PostgreSQL credentials):

PGHOST=localhost
PGPORT=5432
PGUSER=your_username
PGPASSWORD=your_password
PGSSLNEGOTIATION=disable
PGDATABASE=blogs

Example:

PGHOST=localhost
PGPORT=5432
PGUSER=architxkumar
PGPASSWORD=architxkumar
PGSSLNEGOTIATION=disable
PGDATABASE=blogs

Step 6: Run the Application

Start the server:

go run main.go

You should see output indicating the server is running. The API will be available at http://localhost:8080

Step 7: Test the API

Test that the API is working by making a request:

Using curl:

# Get all posts
curl http://localhost:8080/posts

# Create a new post
curl -X POST http://localhost:8080/posts \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My First Blog Post",
    "content": "This is the content of my first blog post.",
    "category": "Technology",
    "tags": ["Tech", "Programming"]
  }'

Using a browser:

  • Open your browser and navigate to http://localhost:8080/posts
  • You should see a JSON response with all blog posts

Troubleshooting

Database connection errors:

  • Verify PostgreSQL is running: pg_isready
  • Check your credentials in .env.development
  • Ensure the database blogs exists: psql -U your_username -l

Port already in use:

  • The application runs on port 8080 by default
  • Check if another application is using the port: lsof -i :8080 (macOS/Linux)
  • Kill the process or modify the port in main.go

Go module errors:

  • Delete go.sum and run go mod download again
  • Run go mod tidy to clean up dependencies

API Endpoints

Create Blog Post

Create a new blog post.

Endpoint: POST /posts

Request Body:

{
  "title": "My First Blog Post",
  "content": "This is the content of my first blog post.",
  "category": "Technology",
  "tags": ["Tech", "Programming"]
}

Validation Rules:

  • title: Required, maximum 255 characters
  • content: Required
  • category: Optional, maximum 30 characters
  • tags: Optional, array of strings

Success Response (201 Created):

{
  "id": 1,
  "title": "My First Blog Post",
  "content": "This is the content of my first blog post.",
  "category": "Technology",
  "tags": ["Tech", "Programming"],
  "created_at": "2021-09-01T12:00:00Z",
  "updated_at": "2021-09-01T12:00:00Z"
}

Error Responses:

  • 400 Bad Request - Invalid JSON format or empty request body
  • 422 Unprocessable Entity - Validation errors (empty title, title too long, empty content, category too long)

Update Blog Post

Update an existing blog post.

Endpoint: PUT /posts/{id}

URL Parameters:

  • id (integer, required) - The ID of the blog post to update

Request Body:

{
  "title": "My Updated Blog Post",
  "content": "This is the updated content of my first blog post.",
  "category": "Technology",
  "tags": ["Tech", "Programming", "Updated"]
}

Validation Rules:

  • Same as Create Blog Post
  • ID must be a positive integer

Success Response (200 OK):

{
  "id": 1,
  "title": "My Updated Blog Post",
  "content": "This is the updated content of my first blog post.",
  "category": "Technology",
  "tags": ["Tech", "Programming", "Updated"],
  "created_at": "2021-09-01T12:00:00Z",
  "updated_at": "2021-09-01T12:30:00Z"
}

Error Responses:

  • 400 Bad Request - Invalid ID format or validation errors
  • 404 Not Found - Blog post with the given ID not found
  • 422 Unprocessable Entity - Validation errors

Delete Blog Post

Delete an existing blog post.

Endpoint: DELETE /posts/{id}

URL Parameters:

  • id (integer, required) - The ID of the blog post to delete

Success Response (204 No Content): No response body

Error Responses:

  • 400 Bad Request - Invalid ID format
  • 404 Not Found - Blog post with the given ID not found

Get Single Blog Post

Retrieve a single blog post by ID.

Endpoint: GET /posts/{id}

URL Parameters:

  • id (integer, required) - The ID of the blog post to retrieve

Success Response (200 OK):

{
  "id": 1,
  "title": "My First Blog Post",
  "content": "This is the content of my first blog post.",
  "category": "Technology",
  "tags": ["Tech", "Programming"],
  "created_at": "2021-09-01T12:00:00Z",
  "updated_at": "2021-09-01T12:00:00Z"
}

Error Responses:

  • 400 Bad Request - Invalid ID format
  • 404 Not Found - Blog post with the given ID not found

Get All Blog Posts

Retrieve all blog posts.

Endpoint: GET /posts

Success Response (200 OK):

[
  {
    "id": 1,
    "title": "My First Blog Post",
    "content": "This is the content of my first blog post.",
    "category": "Technology",
    "tags": ["Tech", "Programming"],
    "created_at": "2021-09-01T12:00:00Z",
    "updated_at": "2021-09-01T12:00:00Z"
  },
  {
    "id": 2,
    "title": "My Second Blog Post",
    "content": "This is the content of my second blog post.",
    "category": "Lifestyle",
    "tags": ["Life", "Tips"],
    "created_at": "2021-09-01T12:30:00Z",
    "updated_at": "2021-09-01T12:30:00Z"
  }
]

Search Blog Posts

Search and filter blog posts by a search term. The search is performed on the title, content, and category fields using a wildcard (LIKE) query.

Endpoint: GET /posts?term={search_term}

Query Parameters:

  • term (string, optional) - Search term to filter posts

Example Request:

GET /posts?term=tech

This will return all blog posts that contain "tech" (case-insensitive) in their title, content, or category.

Success Response (200 OK):

[
  {
    "id": 1,
    "title": "My First Blog Post",
    "content": "This is the content about technology.",
    "category": "Technology",
    "tags": ["Tech", "Programming"],
    "created_at": "2021-09-01T12:00:00Z",
    "updated_at": "2021-09-01T12:00:00Z"
  }
]

Notes:

  • If no term parameter is provided, all posts are returned (same as Get All Blog Posts)
  • The search is case-insensitive
  • The search performs a wildcard match (partial matching)

Project Structure

Blogging-Platform-API/
├── main.go                    # Application entry point
├── internal/
│   ├── handler/               # HTTP request handlers
│   │   ├── task_creation.go   # POST /posts handler
│   │   ├── task_updation.go   # PUT /posts/{id} handler
│   │   ├── deletion.go        # DELETE /posts/{id} handler
│   │   └── retrival.go        # GET /posts and /posts/{id} handlers
│   ├── middleware/            # HTTP middlewares
│   │   ├── logging.go         # Request logging
│   │   ├── request_id.go      # Request ID generation
│   │   └── validation.go      # Input validation
│   ├── model/                 # Data models
│   │   └── post.go            # Post and PostDTO structs
│   └── db/                    # Database files
│       ├── schema.sql         # Database schema
│       └── sample_posts_insert.sql  # Sample data
├── .env.development           # Environment configuration
├── go.mod                     # Go module definition
└── README.md                  # This file

Error Handling

The API uses standard HTTP status codes:

  • 200 OK - Successful GET or PUT request
  • 201 Created - Successful POST request
  • 204 No Content - Successful DELETE request
  • 400 Bad Request - Invalid request format or parameters
  • 404 Not Found - Resource not found
  • 422 Unprocessable Entity - Validation errors
  • 500 Internal Server Error - Server-side errors

All error responses include a descriptive error message in the response body.

Features Not Implemented

The following features are intentionally not implemented as per project requirements:

  • Pagination
  • Authentication
  • Authorization
  • Rate limiting

License: MIT

Author: Archit Kumar

Repository: https://github.com/architxkumar/Blogging-Platform-API


Note: This README documentation was generated with AI assistance due to time constraints. However, all the API implementation logic, database schema, handlers, middleware, and core functionality were developed by Archit Kumar.

About

A RESTful API for a personal blogging platform

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •