Skip to main content
Dat 3rd Sem Fall 2025
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Trip Planning API

This document is an exam assignment for 3rd semester Datamatiker students at EK. The assignment is done in 5 hours at home and submitted as a GitHub repository link to wiseflow (I skal ikke aflevere denne prøveeksamen). After submission, the code in the the main branch must no longer be changed. The student presents their solution in a 30-minute oral exam, where the code is discussed and further development will be requested.

Background

The Trip Planning Application is a backend system for an e-commerce platform offering guided travel experiences. Users can browse, create, update, and delete trips, view available guides, and see relevant packing lists fetched from an external API based on trip category.

The system exposes REST endpoints via Javalin, uses JPA/Hibernate for persistence, integrates with an external packing list API, and includes JWT-based authentication and REST testing.


Non-Functional Requirements

CategoryRequirement
Architecture & TechnologyThe backend must be built using Java, Javalin, and JPA/Hibernate.
Data PersistenceEntities and DAOs must use JPA annotations and connect through a Hibernate configuration.
DTO UsageAll REST communication must use DTOs to decouple internal entities from exposed data.
API DesignThe system must expose RESTful endpoints that conform to standard HTTP methods (GET, POST, PUT, DELETE).
Error Handling and ValidationAll exceptions must be returned as structured JSON objects with appropriate HTTP status codes. Validation of input must be demonstrated and return meaningful error messages.
External IntegrationThe system must consume an external Packing API for each trip’s category and include the retrieved packing data in the trip responses.
TestingEach REST endpoint must be tested using JUnit and Rest Assured, including data setup and teardown.
SecurityThe system must implement JWT authentication, support role-based access control, and secure all endpoints except login and register.
DocumentationThe system must include a clear README.md describing endpoints, test results, and any design decisions.
MaintainabilityCode should be modular, with a clean separation between layers (Controller, DAO, DTO, Entity, Routes).
ReliabilityUnit and integration tests must be performed for all critical business logic and API endpoints.
Data IntegrityDeleting a trip or guide must handle cascading relationships correctly and safely.

User Stories

US-1: As a system administrator

I want to configure the database connection and entity management using Hibernate
so that the application can persist and retrieve trip and guide data reliably.

  • Each trip has a name, start and end times, location coordinates, price, and category (e.g., beach, city, forest, lake, sea, snow).
  • Each guide has personal information (name, email, phone, years of experience) and can be associated with one or more trips.

Acceptance Criteria

  • The system must include entities for Trip and Guide with proper JPA relationships.
  • The system must initialize with sample data via a Populator class.

US-2: As a developer

I want to create, read, update, and delete trip and guide records through DAOs
so that I can manage data consistently across the application.

Acceptance Criteria

  • TripDAO implements CRUD and allows linking trips and guides.
  • GuideDAO implements basic CRUD as needed.
  • DTOs are used for all data exchange between layers.

US-3: As a REST API consumer

I want to manage trips using HTTP endpoints
so that I can perform standard CRUD operations and attach guides to trips.

Acceptance Criteria

  • GET /trips returns all trips.
  • GET /trips/{id} returns trip details including guide and packing items.
  • POST /trips creates a trip.
  • PUT /trips/{id} updates a trip.
  • DELETE /trips/{id} deletes a trip.
  • PUT /trips/{tripId}/guides/{guideId} links an existing guide to a trip.

US-4: As a trip planner

I want to view and filter trips by category
so that I can easily find trips that fit a specific travel type.

Acceptance Criteria

  • A GET /trips?category={category} endpoint filters trips by category using JPA or streams.

US-5: As an analyst

I want to see the total value of trips offered by each guide
so that I can analyze guide performance and revenue contribution.

Acceptance Criteria

  • Endpoint: GET /trips/guides/totalprice returns JSON with each guide’s ID and total trip price sum.

US-6: As a traveler

I want to see recommended packing items for my trip’s category
so that I know what to bring along.

Acceptance Criteria:

  • When retrieving a trip by ID, the response must include packing items fetched from the external API.
  • A separate endpoint provides the total packing weight per trip (GET /trips/{id}/packing/weight).

Details about the external Packing API

  • The external API is available at https://packingapi.cphbusinessapps.dk/packinglist/{category}.

  • The available categories are beach, city, forest, lake, sea and snow.

  • The API returns a JSON object with a list of items to pack for the trip in this format:

{
  "items": [
    {
      "name": "Beach Umbrella",
      "weightInGrams": 1200,
      "quantity": 1,
      "description": "Sunshade umbrella for beach outings.",
      "category": "beach",
      "createdAt": "2024-10-30T17:44:58.547Z",
      "updatedAt": "2024-10-30T17:44:58.547Z",
      "buyingOptions": [
        {
          "shopName": "Sunny Store",
          "shopUrl": "https://shop3.com",
          "price": 50
        },
        {
          "shopName": "Beach Essentials",
          "shopUrl": "https://shop4.com",
          "price": 55
        }
      ]
    },
    ...
  ]
}

NB: The date format for createdAt and updatedAt is ZonedDateTime format, like 2024-10-30T17:44:58.547Z. Jackson might need an extra dependency to handle this format, and this custom configuration of the ObjectMapper:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

US-7: As a tester

I want automated tests for all REST endpoints
so that the application’s functionality is verified and regressions are avoided.

Acceptance Criteria:

  • Each endpoint has corresponding unit/integration tests.
  • Tests set up mock data and verify JSON responses and status codes.
  • Trip-by-ID tests confirm packing data is included.

US-8: As a secure API consumer

I want to log in and access protected endpoints using a JWT token
so that only authorized users can modify or view sensitive data.

Acceptance Criteria:

  • POST /login authenticates and returns a JWT.
  • Protected endpoints validate the token and enforce roles.
  • Unauthorized requests return 401 Unauthorized.
  • Tests verify secure access behavior.

Grading Criteria

DimensionPointsWhat to consider
REST design & correctness15Endpoints, status codes, DTO shapes
Data model & JPA mapping20Relations, cascading, constraints
Packing API integration15Correct call, timeout handling, inclusion in responses
Security (JWT + roles)15Middleware, claims, enforcement
Testing20Coverage of success & failure paths, isolation
Error handling & validation10Consistent JSON errors, field errors
Code quality & README5Structure, clarity, how-to-run
Total100