KotlinCS 124 LogoJava

GET /course/ Redux

In this brief lesson, we’ll discuss some potential problems with the way we saw many students implementing their server GET /course/ method for MP2. And we’ll challenge you to implement a better solution via a homework problem.

MP2 GET /course/ Method
MP2 GET /course/ Method

One of the first parts of MP2 was to implement a method as part of Server.java that responded to requests for routes of the form /course/CS/124 with course details. Many of you were able to get this to work, which is fantastic!

However, we noticed a few things that many of you could improve. Specifically, here are a few problems that we noticed on many submissions that passed the tests:

  1. Reloading courses.json on each request
  2. Deserializing courses.json on each request
  3. Performing a linear search on a linear data structure containing course details, rather than using a more intelligent approach
  4. Manually extracting information from courses.json using String parsing, which won’t work in general and defeats the purpose of deserialization entirely

To be clear, if you passed the tests, then congrats. However, if you made some of these mistakes and showed this code to someone, they might have concerns about your understanding of core language features. So we’re going to return to this problem on a homework problem, where we can help guide you in the right direction.

Note that our concern here is not simply efficiency. Yes, reloading or reparsing courses.json on every request is in fact inefficient. But, more importantly, it’s also unnecessary. Ditto with performing a linear search, given that we’ve discussed a data structure that makes lookups fast and simple.

Reimplementing GET /course/
Reimplementing GET /course/

The homework problem below is set up to mirror the GET /course/ test case from MP2. It’s not quite identical: the problem below has you throw an exception rather than returning an HTTP error code, and it does not support a GET /summary/ route.

You are free to reuse the code that you submitted for MP2. However, if you made some of the mistakes listed above, you will find that you will need to adjust your approach. Here are some hints:

We want to support you as you learn to write code that is not only correct, but idiomatic, elegant, and displays an understanding of how to use language features appropriate. We hope that once you complete this problem you will return to your MP2 submission and improve your getCourse method if it suffered from some of the flaws listed above. But that’s up to you.

Homework: AY2023 MP2: Get Courses Route

Created By: Geoffrey Challen
/ Version: 2023.11.0

Let's return to a portion of the 2023–2024 project and examine how to correctly set up a route to deliver course details.

Complete the provided Server class adding a getCourse route that accepts a non-null path String and returns a JSON object containing details about the requested course. Valid paths will be in the following format: /course/CS/124, where the path indicates a request for details about a course with subject "CS" and number "124". If the path provided is invalid, throw an IllegalArgumentException. If the path provided is valid but the course does not exist, throw an IllegalStateException. Otherwise, return the requested course object as a JSON String.

You will need to load course information out of a courses.json file, which contains a list of JSON objects in the following format:

[
{ "subject": "CS", "number": "124", "label": "CS1", "description": "The best course." },
{ "subject": "CS", "number": "107", "label": "DS1", "description": "Another course." },
...
]

The starter code should get you going this the process of loading the JSON into a String. You'll need to parse the String as JSON to extract the information it contains. Classes from the Jackson serialization library under com.fasterxml.jackson.core are available to help with this. In addition, you can use a Course class without an import that is set up with a shape matching the data in courses.json.

A few hints to get you started:

  • Do not attempt to manually parse the courses.json String using String methods like substring. The contents are JSON, but the format is intentionally irregular to prohibit this approach. Use Jackson to properly deserialize the String.
  • getCourse should not contain a loop. Solutions that do will timeout.
  • You may need a loop in the constructor, but that should be the only place you need one.

There are several ways to approach this problem, but all valid solutions use serialization (or deserialization), and a data structure that facilitates lookups.

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Server {
public Server() throws IOException {
String json =
new Scanner(new File("courses.json"), StandardCharsets.UTF_8).useDelimiter("\\A").next();
ObjectMapper objectMapper = new ObjectMapper();
}
}

More Practice

Need more practice? Head over to the practice page.