blog

module
v0.0.0-...-60bd52b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2025 License: AGPL-3.0

README

Micro Blog

A simple blog system using microservices

image

Features

  • Microservices-based architecture (Users, Posts, Comments, Web)
  • Minimalist web UI (feed, profiles, login, signup)
  • AI co-authoring for posts (OpenAI integration)
  • Tagging and tag-based filtering for posts
  • ActivityPub federation (Fediverse support: actors, inbox/outbox, followers, following, WebFinger)
  • Persistent key and follower management for ActivityPub
  • REST API for all major features
  • GitHub Actions CI for Go tests
  • Licensed under AGPL v3

Contents

Services

The project consists of the following microservices:

  1. Users: User management (create, read, update, delete)
  2. Posts: Post management (create, read, delete, list, tag management, AI co-authoring)
  3. Comments: Comment management (create, read, delete, list)
  4. Web: REST API and web app that uses all other services

Web Interface

A minimalist web interface for the blog, located in web/static/:

  • index.html: Main feed, create posts, view posts and comments
  • login.html: User login page
  • signup.html: User registration page
  • profile.html: User profile, posts, and comments

Everything is server side rendered

AI Co-authoring Feature

The blog includes an AI co-authoring feature that allows users to generate post content with the help of AI. When creating a post, users can:

  1. Enter a title and a brief description or outline of what they want to write about
  2. Click "Write with AI" to generate a full post based on their description
  3. Edit the generated content before posting
Configuration

To use the AI co-authoring feature, you need to set your OpenAI API key as an environment variable:

export OPENAI_API_KEY=your_openai_api_key

Then start the posts service. The service will log whether the AI co-authoring feature is enabled based on the API key configuration.

Tag Features

The blog allows you to:

  • Add tags to posts
  • Remove tags from posts
  • Filter the feed to show posts with a specific tag
  • Browse all available tags

Getting Started

Prerequisites
  • Go 1.24 or higher
  • Micro v5 (master branch)

To install Micro CLI:

go install github.com/micro/micro/v5@master

Make sure that $GOPATH/bin (or $HOME/go/bin) is in your PATH so you can use the micro command.

Launching Services

If you have Micro installed, you can run all services at once from the project root:

micro run

Browse to http://localhost:8081

API Endpoints

Posts
  • GET /posts: List all posts
  • GET /posts/:id: Get a post by ID
  • POST /posts: Create a new post
    {
      "title": "Post title",
      "content": "Post content"
    }
    
Comments
  • GET /comments: List all comments (optionally filter by post_id query param)
  • POST /comments: Add a comment
    {
      "content": "Comment content",
      "post_id": "post_id"
    }
    
Users
  • GET /users: List all users
  • GET /users/:id: Get a user by ID
  • POST /users: Create a new user
    {
      "name": "User Name",
      "email": "email@example.com"
    }
    
  • POST /signup: Register a new user (and log in)
    {
      "name": "User Name",
      "email": "email@example.com",
      "password": "plaintextpassword"
    }
    
  • POST /login: Log in as a user
    {
      "email": "email@example.com",
      "password": "plaintextpassword"
    }
    
  • POST /logout: Log out the current user
  • GET /users/me: Get the current session user info
Tags
  • POST /posts/:id/tags: Add a tag to a post
    {
      "tag": "tagname"
    }
    
  • DELETE /posts/:id/tags/:tag: Remove a tag from a post
  • GET /tags: Get all available tags
  • GET /tags?post_id=:id: Get tags for a specific post
  • GET /posts/by-tag/:tag: Get posts with a specific tag

ActivityPub & Federation Support

This blog platform supports ActivityPub federation, allowing your blog to participate in the decentralized social web (Fediverse).

Features
  • ActivityPub Actor: Each user is discoverable as an ActivityPub actor at /users/:username/actor.
  • Inbox/Outbox: Implements /users/:username/inbox and /users/:username/outbox for receiving and publishing activities.
  • Followers/Following: Exposes /users/:username/followers and /users/:username/following endpoints. Followers are stored persistently.
  • WebFinger Discovery: Supports /.well-known/webfinger for user discovery by remote servers.
  • Federated Posting: When a user is followed by remote Fediverse users, new posts are automatically sent as ActivityPub Create activities to all followers' inboxes.
  • Persistent Follower Storage: Followers are stored using go-micro.dev/v5/store for reliability and scalability.
  • Inbox Accepts: Handles incoming Follow requests and responds with Accept activities.
  • Outbox: Exposes all user posts as ActivityPub Create activities for remote consumption.
How it Works
  • When a remote user follows a blog user, their inbox URL is stored as a follower.
  • When a new post is published, a Create activity is sent to all followers' inboxes.
  • Followers are managed in persistent storage, not just in memory.
  • The outbox endpoint lists all posts as ActivityPub activities for the user.
Example Endpoints
  • GET /.well-known/webfinger?resource=acct:alice@example.com – WebFinger discovery
  • GET /users/alice/actor – ActivityPub actor for Alice
  • POST /users/alice/inbox – Receive ActivityPub activities (Follow, Like, etc.)
  • GET /users/alice/outbox – List Alice's posts as ActivityPub Create activities
  • GET /users/alice/followers – List Alice's followers
Usage & Configuration

To enable ActivityPub federation, you must set the DOMAIN environment variable to your public domain name (e.g. example.com). This is required so that outgoing ActivityPub activities use the correct URLs for your actors and posts.

Example:

export DOMAIN=example.com
  • The DOMAIN variable should be set in the environment for all services (especially users, posts, and web).
  • If running locally for testing, you can use localhost or your local IP, but federation will only work with a public domain.

After setting DOMAIN, start your services as usual:

micro run

Your blog will now be discoverable and federated on the Fediverse using your configured domain.

Notes
  • HTTP signatures for outgoing federation are now implemented (recommended for production).
  • Follower management is persistent and robust.
  • The platform is compatible with Mastodon, Friendica, and other Fediverse software.

Project Structure

blog/
├── comments/           # Comments service
│   ├── handler/        # Request handlers
│   ├── main.go         # Entry point
│   └── proto/          # Protobuf definitions
├── posts/              # Posts service
│   ├── handler/
│   ├── main.go
│   └── proto/
├── users/              # Users service
│   ├── handler/
│   ├── main.go
│   └── proto/
└── web/                # REST API and static web UI
    ├── main.go         # REST API server
    └── static/         # Static web UI (index.html, login.html, signup.html, profile.html)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL