- Overview
- Prerequisites
- Getting Started
- Available Routes
- Security and Best Practices
- Custom Middlewares
- API Route Screenshots
This project involves creating a Trip Planner API that interacts with a third-party service to search for trips between specified origins and destinations. The API allows sorting the results based on the fastest or cheapest trips. Additionally, the system includes functionality to manage trips by saving, listing, and deleting them(Trip Manager Bonus). This API offers also a bonus feature for calculating the carbon emissions of flights using the Carbon Interface API.
The project aims to demonstrate proficiency in building a Node.js application with clean architecture and best practices while meeting specific functional requirements.
Functional Requirements:
- The API should allow users to search for trips based on the origin and destination provided.
- The API should support sorting the search results by either the fastest or the cheapest trips.
- The API should enable users to save selected trips for future reference.
- The API should provide an endpoint to list all saved trips.
- The API should allow users to delete a saved trip by its ID.
To run this project, you must have Docker
and Docker Compose
installed on your system. A convenient way to install both is by using Docker Desktop
, which is available for various operating systems:
Docker Desktop Download: https://www.docker.com/products/docker-desktop/
Start by cloning the repository to your local machine:
git clone https://github.com/lisenpasha/trip-planner.git
cd trip-planner
A .env.example
file is included in this repository. You should create a .env file in the root directory of the project, following the format provided in the .env.example file.
You only need to change the API_KEY
variable, which represents the API key provided in the email.
For the CARBON_INTERFACE_API_KEY
, you can use my API key for testing purposes, which is already included in the .env.example
file.
You can start the containers by running:
docker-compose up
This command will start both the application and MongoDB containers.
Note: Before the application is fully up and running, unit tests(15 total) will automatically execute as part of the Docker setup process. You can monitor the results of these tests in the terminal to ensure that everything is functioning correctly. Please ensure that the mongo-1 instance is running and available after tests are completed, before attempting to use the API routes.
Bonus Feature: Carbon Emission Calculation
This API includes an additional feature to calculate the carbon emissions for flights. This feature leverages the Carbon Interface API
to provide users with insights into the environmental impact of their travel.
-
Search Trips
- Endpoint:
/api/trips/search
- Method: GET
- Parameters:
origin
,destination
,sort_by
- Description: Searches for trips between the specified origin and destination, sorted by the specified strategy (fastest or cheapest).
- Endpoint:
-
Save Trip
- Endpoint:
/api/trips
- Method: POST
- Body:
{ "origin": "JFK", "destination": "LAX", "cost": 200, "duration": 300, "type": "flight", "display_name": "NYC to LA", "id": "some-external-id" // This will be saved as external_id in the database }
The
id
field in the request body is saved asexternal_id
in the database. This design allows you to copy a ready object from the API mentioned in the task requirements and paste it directly without further changes. This makes it easy to integrate with other systems or to test the API with pre-existing data.- Description: Saves a new trip to the database.
- Endpoint:
-
List Saved Trips
- Endpoint:
/api/trips
- Method: GET
- Description: Lists all saved trips.
- Endpoint:
-
Delete Saved Trip
- Endpoint:
/api/trips/:id
- Method: DELETE
- Description: Deletes a saved trip by its ID.
- Endpoint:
-
[Extra Feature] Trip Type Filtering and Aggregation
-
Endpoint:
/api/trips/aggregate
-
Method: GET
-
Description: This extra feature filters and aggregates trips based on the specified type (e.g., flights, cars, trains) between the given origin and destination. If a trip type is specified, the API will return the total number of trips, the average cost, and the average duration for that specific trip type.
-
Parameteres: -
origin
(required): The IATA 3-letter code of the origin location.
-destination
(required): The IATA 3-letter code of the destination location.
-type
(required): The type of trip (flight, car, train). -
Example Response:
{ "origin": "SYD", "destination": "GRU", "type": "car", "total_trips": 3, "average_cost": 2412, "average_duration": 19.67 }
-
-
[Extra Feature] Best Value Trip
- Endpoint:
/api/trips/best-value
- Method: GET
- Description: This extra feature calculates and returns the best value trip based on a combination of cost and duration. The
value score
is determined by dividing the cost by the duration, and the trip with the lowest value score is considered the best value. - Parameteres:
-
origin
(required): The IATA 3-letter code of the origin location.
-destination
(required): The IATA 3-letter code of the destination location.
- Endpoint:
This API has been fortified with several security-focused middlewares to protect against common vulnerabilities:
helmet: Helps secure your app by setting various HTTP headers.
express-mongo-sanitize: Prevents NoSQL injection attacks.
xss-clean: Sanitizes user input to prevent cross-site scripting (XSS) attacks.
express-rate-limit: Limits repeated requests to public APIs and endpoints, protecting against brute-force attacks.
hpp: Protects against HTTP parameter pollution attacks.
In addition to the security middlewares mentioned above, the API also includes custom middlewares that are specifically tailored for certain operations, such as:
Delete Trip: Custom middleware to validate and sanitize the trip ID before deletion.
Create New Trip: Custom middleware to validate and sanitize input data when creating a new trip, ensuring that only valid data is processed.
Search Trips: Custom middleware to validate and sanitize the search parameters, ensuring that the correct data is retrieved. These custom middlewares are designed to handle specific validation and sanitization tasks for different API operations, making the API more organized and secure.
In this section, you'll find screenshots demonstrating the usage and responses of each route in the API.
- Search Trips
![image](https://private-user-images.githubusercontent.com/119539599/358329934-cba78843-b13d-4761-b007-b88f1d1bc8be.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk3MDI5MDEsIm5iZiI6MTczOTcwMjYwMSwicGF0aCI6Ii8xMTk1Mzk1OTkvMzU4MzI5OTM0LWNiYTc4ODQzLWIxM2QtNDc2MS1iMDA3LWI4OGYxZDFiYzhiZS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQxMDQzMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT04NzI5Mjk5OTU5ZTM3YmI5MWNhZDcxMTNkMjY4OGM1NWVmNGU3ZTUzY2YzMjM5MTM1MDdjYzAzZDM4ZWRmN2IyJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.jgS_DCGAMOCqa8BHBAYXq1cke-tXPoSuO3hBHvqoonk)
![image](https://private-user-images.githubusercontent.com/119539599/358330033-72598f9d-770e-420b-9edd-b756602d752f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk3MDI5MDEsIm5iZiI6MTczOTcwMjYwMSwicGF0aCI6Ii8xMTk1Mzk1OTkvMzU4MzMwMDMzLTcyNTk4ZjlkLTc3MGUtNDIwYi05ZWRkLWI3NTY2MDJkNzUyZi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQxMDQzMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT02YTQxOWQ1MWZlM2MzODg1YTZmYjBiMGUyMzQ0NmM5MzkzN2FhNWJiNzBhOTVjMjU0NDg3OWU1YzgwMGQ0YTBjJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.ZoPr6fjiSpsqF6Fb_NNPFLX58R7XhIOxlXqfuf25qis)
- Save Trip
![image](https://private-user-images.githubusercontent.com/119539599/358330263-2a5d92b9-f6af-4ae2-af8b-1e7d148f9933.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk3MDI5MDEsIm5iZiI6MTczOTcwMjYwMSwicGF0aCI6Ii8xMTk1Mzk1OTkvMzU4MzMwMjYzLTJhNWQ5MmI5LWY2YWYtNGFlMi1hZjhiLTFlN2QxNDhmOTkzMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQxMDQzMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kMTA2NzZlOGZiMTM1MGNhYjUzYzdmOWJjNTEzNDQ5NTE5NjUyNDBiMmI3NWRjNzk4MGExOTgzMjAwODllZWQ5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.BPY7MkdBnsrrW0YrGgTQyEX_P6wz1GrJPPIo4Eu1RBQ)
- List Saved Trips
![image](https://private-user-images.githubusercontent.com/119539599/358330467-020e9f80-dbb1-40af-b91a-a208f370697f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk3MDI5MDEsIm5iZiI6MTczOTcwMjYwMSwicGF0aCI6Ii8xMTk1Mzk1OTkvMzU4MzMwNDY3LTAyMGU5ZjgwLWRiYjEtNDBhZi1iOTFhLWEyMDhmMzcwNjk3Zi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQxMDQzMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01ZTVkMzY4YmIyNTU3Y2Y5NjM3NTk0YmUwZmFlZGQ2NTIyMDAwZWRjYzhkZGM3M2E5ZjgwMjlhNTAyYThkYTNkJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.YeCnwqKzUwPXmjF74RiB6gGb05OO8fBO9PXxGx3Zlus)
- Delete Saved Trip
![image](https://private-user-images.githubusercontent.com/119539599/358330805-d2e98daf-7743-40ed-8a90-4527b8aa38f4.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk3MDI5MDEsIm5iZiI6MTczOTcwMjYwMSwicGF0aCI6Ii8xMTk1Mzk1OTkvMzU4MzMwODA1LWQyZTk4ZGFmLTc3NDMtNDBlZC04YTkwLTQ1MjdiOGFhMzhmNC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQxMDQzMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1iN2FhMjE1NmY0MzI1OTExZjJjOWM4ZGE2YjNjMGU5N2NiOTY2NDNjMTcwMWQ5OGNkYWNjM2U4ZGMyOTYwMDYxJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.SnMvURwLgUwcmKKzPCqFtU13d4QV4vIt1gN45wsfhNg)
- [Extra Feature] Trip Type Filtering and Aggregation
![image](https://private-user-images.githubusercontent.com/119539599/358331294-cc9d465b-ff25-4f93-9209-27a1125c0e5a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk3MDI5MDEsIm5iZiI6MTczOTcwMjYwMSwicGF0aCI6Ii8xMTk1Mzk1OTkvMzU4MzMxMjk0LWNjOWQ0NjViLWZmMjUtNGY5My05MjA5LTI3YTExMjVjMGU1YS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQxMDQzMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kZGE3ZTk3OWRmNGUxMDcwM2M3MDI5OWNiNDI4OTBjNzI3OTJmNmMwNTc3Yzg4YzcxZDRkYzg4MGE3NTlkMzJmJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.Ibz41dI9nGEmY9Na9drMfIZ-df7HpVuenP_3gUJWMkY)