Micro Blog
A simple blog system using microservices

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:
- Users: User management (create, read, update, delete)
- Posts: Post management (create, read, delete, list, tag management, AI co-authoring)
- Comments: Comment management (create, read, delete, list)
- 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:
- Enter a title and a brief description or outline of what they want to write about
- Click "Write with AI" to generate a full post based on their description
- 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
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
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)