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 π