Start learning free

LESSON 34 OF 173 · BACKEND: YOUR FIRST API

Project: The Shop So Far in Java

Practice

This project puts most of what you have built so far into one new route. A product page shows the product's rating: the average of the stars in its reviews. The rating belongs to one product, so it gets a nested path under that product, just like the reviews: /products/1/rating.

An average in Java: collect the numbers in a list, then divide the total from the sum helper by size(). Multiplying by 100.0, rounding with Math.round and dividing by 100.0 keeps 2 decimal places, the way getStats does for the prices.

List<Integer> temperatures = List.of(20, 23, 22);
double average = Math.round(sum(temperatures) * 100.0 / temperatures.size()) / 100.0;
System.out.println(average);   // 21.67

No numbers, no average: when the list is empty, size() is 0. With 100.0 in it, the division doesn't crash: it gives NaN, "not a number", and Math.round turns that into 0, so the rating would quietly be 0.0, as if every customer gave 0 stars. So check for an empty list first and answer Optional.empty(), which Spring sends as null. A product with no reviews still exists, so it gets 200 with a null rating. A product that isn't in products gets 404, as always.

The test requests, in this order, and what your code must answer:

GET /products/1/rating    →  200  {"product_id": 1, "rating": 4.5}
GET /products/3/rating    →  200  {"product_id": 3, "rating": 2}
GET /products/2/rating    →  200  {"product_id": 2, "rating": null}
GET /products/99/rating   →  404  {"error": "Product not found"}
POST /products/1/reviews  {"stars": 5, "text": "My favourite mug"}  →  201  (the review)
GET /products/1/rating    →  200  {"product_id": 1, "rating": 4.67}
POST /products/2/reviews  {"stars": 3, "text": "Thin pages"}  →  201  (the review)
GET /products/2/rating    →  200  {"product_id": 2, "rating": 3}
DELETE /products/3        →  204  (empty)
GET /products/3/rating    →  404  {"error": "Product not found"}

Your task: at the end of ShopController, add a route for GET /products/{productId}/rating with the method getRating. It answers the "product_id" and a "rating": the average of the product's stars rounded to 2 places, or null when the product has no reviews. When no product has that id, it answers 404 with "Product not found".


Assignment
Follow the Coding Tutorial to add the /rating route below addReview: find the product, collect the stars of its reviews, and answer their rounded average, or a null rating when there are none.


Hint
Copy the shape of getReviews to find the product and to answer the 404 with errorResponse, and the shape of getStats for the list, the empty check and the rounded average. Check for an empty list before you divide.


STEP 1 OF 12
    Ctrl + Enter to check

    Shop Api Recap in Java

    Keep going with Java1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free