A microblogging app built with Go Micro
Yet another microblog. But here's the catch. Rather than just spitting out your thoughts, co-author them with AI instead. Reflect and be more thoughtful. Get instant feedback and rewrite as needed. Or even just put down your thoughts and let the AI reword it for you.
- Microservices-based architecture (Users, Posts, Comments, Web)
- Minimalist web UI (feed, profiles, login, signup)
- Human-first writing with "Edit with AI" (OpenAI integration) and preview-before-apply
- Edit and delete your own posts (author-only controls)
- Tagging, clickable tags, and tag-based browsing (/tags/:tag)
- REST API for all major features
- GitHub Actions CI for Go tests
- Licensed under AGPL v3
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
A minimalist web interface for the blog, located in web/static/:
index.html: Main feed, create posts, view posts and commentslogin.html: User login pagesignup.html: User registration pageprofile.html: User profile, posts, and comments
Everything is server side rendered
The blog takes a human-first approach. You write, and the AI helps refine. There are two places you can use AI:
- On the composer (feed page)
- Enter a title and some content.
- Click "Edit with AI" (renamed from "Write with AI").
- An AI Suggestion preview will appear. You can:
- Use This: apply the suggestion to your draft
- Try Again: generate another suggestion
- Discard: ignore the suggestion
- On the post page (editing an existing post)
- Click "Edit Post" (visible only to the author), then "Re-edit with AI".
- You’ll see the same preview-first flow before applying changes.
Prompt minimization
- To avoid token limits, the app minimizes what it sends to the AI:
- If content is long, it sends the title (if present) and only the first and last paragraphs (or a truncated snippet) as context.
- The backend also safeguards with additional truncation.
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_keyThen start the posts service. The service will log whether the AI co-authoring feature is enabled based on the API key configuration.
The blog allows you to:
- Add tags to posts
- Remove tags from posts
- Click tags on a post to browse posts with that tag
- Filter the feed to show posts with a specific tag at
/tags/:tag - Browse all available tags (API) or filter via UI
Notes
- Tag add/remove from the web UI will redirect you back to the post page on success.
- API/JSON clients receive JSON responses.
- Authors can edit or delete their own posts on the post page.
- Edit opens an inline editor with a "Re-edit with AI" preview flow.
- Delete prompts for confirmation and then returns you to the feed.
- Go 1.24 or higher
- Micro v5 (master branch)
To install Micro CLI:
go install go-micro.dev/v5/cmd/micro@masterMake sure that $GOPATH/bin (or $HOME/go/bin) is in your PATH so you can use the micro command.
Clone and cd into the blog directory and run it
micro runBrowse to http://localhost:8089
GET /posts: List all postsGET /posts/:id: Get a post by IDPOST /posts: Create a new post{ "title": "Post title", "content": "Post content" }PATCH /posts/:id: Update a post (author only){ "title": "Updated title", "content": "Updated content" }DELETE /posts/:id: Delete a post (author only)
GET /comments: List all comments (optionally filter bypost_idquery param)POST /comments: Add a comment{ "content": "Comment content", "post_id": "post_id" }
GET /users: List all usersGET /users/:id: Get a user by IDPOST /users: Create a new user{ "name": "User Name", "email": "[email protected]" }POST /signup: Register a new user (and log in){ "name": "User Name", "email": "[email protected]", "password": "plaintextpassword" }POST /login: Log in as a user{ "email": "[email protected]", "password": "plaintextpassword" }POST /logout: Log out the current userGET /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 postGET /tags: Get all available tagsGET /tags?post_id=:id: Get tags for a specific postGET /posts/by-tag/:tag: Get posts with a specific tagGET /tags/:tag: HTML page showing posts filtered by tag (same template as the main feed)
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)