Between January and April 2025 I built PetsFirst Health, at health.petsfirst.care. Pet parents in Bengaluru use it to book a vaccination at home, a blood test at home with the report in 24 hours, or a surgery or hospital visit.
I built all of it: the website, the API, the database model, the mobile app, and the AWS setup. This post is about how the pieces fit together.
The stack
- Website: Next.js
- API: Node.js and Express
- Database: MongoDB
- Mobile app: Flutter
- Hosting: AWS, deployed through a CI/CD pipeline from GitHub
One API, two clients
The website and the Flutter app call the same Express API. There is no endpoint made only for mobile, and no business logic inside either client. The clients show screens and send input. Prices, slots, booking rules and records are decided in the API.
This sounds easy and it is hard to hold. Many times a slightly different endpoint just for the app would have saved me an hour that day. I kept saying no. Because of that, a feature is built once and shows up on both the website and the app. And the API stays small enough for one person to keep in their head.
One thing I learned here: Next.js makes it very easy to put logic in its own server side, in API routes or server components. If I had done that, the Flutter app could not reuse it. So in this project Next.js is only a front end. It calls the Express API like the app does.
The mobile app changes how you treat the API
I can redeploy the website in minutes. If I break an endpoint for the website, I fix both sides in one deploy.
The app is different. If I change an endpoint in a way the installed app does not expect, it stays broken on every phone until the user updates. I cannot force that update.
So I change the API by adding. New fields are fine. Removing or renaming a field that the app reads is a decision, not a cleanup.
Why MongoDB
The data has the shape of documents. A pet has records, appointments and history, and they sit naturally inside each other.
The three services also look different from each other. A vaccination has a vaccine and a date. A blood test ends with a lab report. A surgery has a hospital and a procedure. Their fields kept changing while I was building. With documents I could add a field to one service without a migration for the other two.
The risk with MongoDB is that “flexible” turns into “anything goes”, and then no two documents look the same. So I still keep a defined shape for each kind of document in the API code. The database being flexible does not mean the code should be.
Where it is now
The platform is live. Besides vaccinations, blood tests and surgery booking, it also has an online pet pharmacy, travel certificates and online vet consultations.