Building a multi-tenant blogging platform requires thoughtful design of the API to ensure clarity, scalability, and security. In this post, we’ll explore a RESTful API design including versioning, nested resources, and authentication, using clear examples and best practices.
๐งฉ Understanding the Requirements
Before diving into endpoints, let’s break down what the platform supports:
- Multiple tenants (e.g., organizations, teams)
- Each tenant has users
- Users can create blogs, and each blog has posts
- Posts can have comments
- Authentication is required
๐ Versioning
Weโll use URI-based versioning:
/api/v1/
This helps manage breaking changes cleanly.
๐ Authentication
We’ll use token-based authentication (e.g., JWT or API keys). Each request must include:
Authorization: Bearer <token>
๐ Base URL
https://api.blogcloud.com/api/v1
๐ API Endpoint Design
๐ธ Tenants
Tenants are top-level entities.
GET /tenantsโ List all tenants (admin only)POST /tenantsโ Create a new tenantGET /tenants/:idโ Show tenant detailsPATCH /tenants/:idโ Update tenantDELETE /tenants/:idโ Delete tenant
๐ธ Users (Scoped by tenant)
GET /tenants/:tenant_id/usersโ List users for tenantPOST /tenants/:tenant_id/usersโ Create userGET /tenants/:tenant_id/users/:idโ Show userPATCH /tenants/:tenant_id/users/:idโ Update userDELETE /tenants/:tenant_id/users/:idโ Delete user
๐ธ Blogs (Belong to users)
GET /tenants/:tenant_id/users/:user_id/blogsโ List blogsPOST /tenants/:tenant_id/users/:user_id/blogsโ Create blogGET /tenants/:tenant_id/users/:user_id/blogs/:idโ Show blogPATCH /tenants/:tenant_id/users/:user_id/blogs/:idโ Update blogDELETE /tenants/:tenant_id/users/:user_id/blogs/:idโ Delete blog
๐ธ Posts (Belong to blogs)
GET /blogs/:blog_id/postsโ List postsPOST /blogs/:blog_id/postsโ Create postGET /blogs/:blog_id/posts/:idโ Show postPATCH /blogs/:blog_id/posts/:idโ Update postDELETE /blogs/:blog_id/posts/:idโ Delete post
๐ธ Comments (Belong to posts)
GET /posts/:post_id/commentsโ List commentsPOST /posts/:post_id/commentsโ Add commentDELETE /posts/:post_id/comments/:idโ Delete comment
โQuestion: what is the full url of comments?
No, the full URL for comments should not be:
https://api.blogcloud.com/api/v1/tenants/:tenant_id/users/:user_id/blogs/posts/:post_id/comments
That nesting is too deep and redundant, because:
- By the time you’re at a post, you already implicitly know which blog/user/tenant it’s under (assuming proper authorization).
- Posts have unique IDs across the system (or at least within blogs), so we donโt need the entire hierarchy in every request.
โ Correct RESTful URL for Comments
If your post_id is unique (or unique within a blog), the cleanest design is:
https://api.blogcloud.com/api/v1/posts/:post_id/comments
or, if you prefer to keep blog_id context:
https://api.blogcloud.com/api/v1/blogs/:blog_id/posts/:post_id/comments
Use that second version only if post_id is not globally unique, and you need the blog context.
๐ Recap of Comments Endpoints
| Action | HTTP Verb | Endpoint |
|---|---|---|
| List comments | GET | /api/v1/posts/:post_id/comments |
| Create comment | POST | /api/v1/posts/:post_id/comments |
| Delete comment | DELETE | /api/v1/posts/:post_id/comments/:id |
๐ง Design Rule of Thumb
- โ Keep URLs meaningful and shallow.
- โ Don’t over-nest resources unless it’s needed to enforce scoping or clarify context.
๐ฅ Example: Create a Blog Post
Request:
POST /blogs/123/posts
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "Why REST APIs Still Matter",
"body": "In this post, we explore the benefits of RESTful design..."
}
Response:
201 Created
{
"id": 456,
"title": "Why REST APIs Still Matter",
"body": "In this post, we explore the benefits of RESTful design...",
"created_at": "2025-07-03T10:00:00Z"
}
โ Best Practices Followed
- Nesting: Resources are nested to show ownership (e.g., blogs under users).
- Versioning: Prevents breaking old clients.
- Consistency: Same verbs and JSON structure everywhere.
- Authentication: Every sensitive request requires a token.
๐ง Final Thoughts
Designing a RESTful API for a multi-tenant app like a blogging platform requires balancing structure and simplicity. By properly scoping resources, using versioning, and enforcing auth, you build an API that’s powerful, secure, and easy to maintain.
Bonus Tip: Document your API using tools like Swagger/OpenAPI to make onboarding faster for new developers.
You are an awesome Architect ๐