← back to all projects
Link Vault API
Part 3 — Express + MongoDB
Why This Project
Think of this as a Pocket/Raindrop.io clone backend. You save URLs you want to
read later, tag them, and search through them. This is a more interesting domain
than a generic CRUD app because it involves URL validation, tagging systems (arrays
in MongoDB), text search, and sorting — real problems you'd solve in a production API.
What to Build
A REST API for saving and organizing bookmarks. Each link has a URL, a title
(auto-fetched from the page or user-provided), tags (array of strings), a
"read" boolean, and timestamps. Support filtering by tags, searching by title,
and sorting by date added or alphabetically. Deploy to a cloud service.
Requirements
- Express with middleware: JSON parser, cors, morgan logger, custom error handler
- Mongoose model with validation: URL must be valid format, title required, tags as [String]
- GET /api/links — supports query params:
?tag=javascript, ?search=react, ?sort=title, ?read=false
- POST /api/links — saves a new bookmark
- PUT /api/links/:id — update (e.g., mark as read, edit tags)
- DELETE /api/links/:id
- GET /api/tags — returns all unique tags with count of links per tag
- MongoDB text index on title for search functionality
- Custom error handling middleware that distinguishes validation errors, cast errors, and duplicate key errors
- Environment variables via dotenv
- Deploy to Fly.io or Render with MongoDB Atlas
- Test all endpoints with REST Client or Thunder Client
Skills Practiced
Express
MongoDB
Mongoose
query params
text search
array fields
aggregation
error middleware
validation
deployment
Pain Point to Notice
The GET /api/tags endpoint is your first encounter with MongoDB aggregation — you
can't just do a simple find() to get unique tags with counts. You'll need to unwind
the tags array and group by tag name. This is where you start seeing that MongoDB
isn't just "JSON in a database" — it has its own query language and pipeline system.