Elentra Car API is a Node.js car management REST API I architected and built as the backend for car management systems. It handles vehicle data operations, user management and third-party integrations through RESTful Express endpoints, with MongoDB and Mongoose for storage, JWT for authentication and authorization, and Postman for testing. It was designed to support high-traffic applications.
The problem
A car management system asks more of its data than a typical CRUD app. Each vehicle record holds many fields, and different screens want the same cars in different shapes: a list needs a summary, a detail page needs everything, an admin view needs to edit it. Reads far outnumber writes, so the backend has to answer common queries quickly without sending more than each screen needs.
On top of the vehicle data, the API manages user accounts, decides which users may do what, and exchanges data with outside services through third-party integrations. It was also meant to support high-traffic applications, which ruled out designs that only hold up under light load, such as keeping session state in one server's memory.
My role
I architected and developed the backend: the route structure, the Mongoose models for vehicles and users, the authentication and authorization layer, the error handling and logging middleware, the third-party integrations, and the Postman collection used to test it. The screenshot shows the Elentra front end; this case study is about the API side.
Architecture and tech stack
Resource-based REST routes in Express
Cars and users are modelled as resources with predictable URLs and standard HTTP methods. Each resource has its own Express router and controller, which keeps route files short and lets a client developer guess an endpoint without opening the code. Status codes are chosen deliberately, so a client can tell a missing car from a validation failure or a permission problem.
Mongoose models built around how cars are read
Since most traffic is reads, the vehicle schema is shaped for the queries clients make most often, with indexes on the fields used to filter and sort listings. List endpoints return only the fields a list view needs, and the full document comes from the detail route. Schema and index design did the same job at a larger scale in the Cyborg Gaming Node.js backend, where it cut query times.
Stateless authentication with JWT
For an API expected to take heavy traffic, server-side sessions would force every instance to share a session store. A signed JWT lets any instance verify a request on its own. One middleware checks the token, a second checks what that user is allowed to do, and both run before the controller, so permission logic stays out of the individual handlers.
One error handler and logging middleware
Controllers pass failures on to a single Express error handler instead of each writing its own response. That handler turns validation errors, missing records and unexpected exceptions into consistent JSON with the correct status code, and logs the detail on the server, so clients never receive a stack trace while I still have one to debug from.
Key features
- RESTful endpoints for every car operation: listing, reading, creating, updating and removing vehicles.
- Authentication and authorization with JWT: protected routes are checked by middleware before any controller runs.
- Optimised MongoDB data models for vehicle information, defined as Mongoose schemas with validation and indexes.
- Error handling and logging middleware that returns errors in one consistent format and records what went wrong.
- Third-party integrations that connect the API to outside services.
- A Postman collection covering the endpoints, used to test the API as it was built.
Challenges and how I solved them
Keeping vehicle data valid from every entry point
- Problem
- Cars can be written from more than one place, including the third-party integrations. If validation lives only in a route handler, every new entry point is another chance for incomplete or mistyped records to reach the database.
- Solution
- Validation sits in the Mongoose schemas, where required fields, types and allowed values are declared once. Anything that writes a car goes through the same model, so the collection only holds records the clients can depend on.
Outside services that fail on their own schedule
- Problem
- An integration is code that depends on someone else's uptime. A slow or failing outside service should not take a car request down with it, or leave a client waiting until it times out.
- Solution
- Calls to outside services are wrapped so their failures are caught, logged through the same middleware and returned as a clear error response instead of crashing the process. The rest of the API keeps answering while an integration is unavailable.
Testing an API that has no screen of its own
- Problem
- A backend's bugs should not wait for a front end to discover them. Testing by hand with one-off requests is easy to skip and impossible to repeat exactly after a change.
- Solution
- I kept a Postman collection with a request for each endpoint, including the failure cases: missing or expired tokens, invalid ids and malformed vehicle data. Running the collection again after a change showed quickly whether anything had broken, and it gave client developers a working reference for every route.
Results
The result is a Node.js car management REST API a front end can build on: predictable routes for vehicles and users, authentication handled once in middleware, and errors that come back in the same shape every time. It was designed for high-traffic applications, and stateless authentication and indexed reads are the two choices that design rests on.
The token-based approach is the same one behind the team management system with three-tier access control, applied here to an API that serves other applications rather than its own interface.
What's next
Next I would add rate limiting and response caching for the busiest read endpoints, and publish OpenAPI documentation generated from the routes so client developers are not relying on the Postman collection alone.
