Skip to content

Lab 5 - HTTP API - POST

Goal

Implement a POST API that will create a new coffee order and store it in the Repository. You will be sending JSON to create the order.


References

This reference of annotations might be helpful: http://engineering.pivotal.io/post/must-know-spring-boot-annotations-controllers/


Run *all* your tests to make sure everything is still working before continuing.


Create Request DTO

  1. Create a new class, CoffeeOrderCreateRequest that is a DTO (JavaBean) that has the following properties:

    • name as a String
    • size as a String
    • creamer as a String
    • sweetener as a String
  2. Generate getters and setters for all four properties using CMD+N.

Orders Have Names

Since it'd be useful to know who is placing the coffee order, add a name property to the CoffeeOrder as follows:

  1. Open up the CoffeeOrder class and add a new member variable called name which is of type String

    • Instead of adding a setter/getter, since name is an intrinsic property of the order, you'll add two methods:

      • name() that returns its name (a query)
      • changeNameTo(String newName) that updates the name to the new value (a command)
  2. Modify the CoffeeOrderDataLoader class so that in the run method, all orders are given a name, e.g.:

    CoffeeOrder coffeeOrder1 = new CoffeeOrder();
    coffeeOrder1.size(SizeOption.MEDIUM);
    coffeeOrder1.changeNameTo("Megan");
    coffeeOrderRepository.save(coffeeOrder1);
    
    // change names for other orders too...
    
  3. Update the CoffeeOrderApiControllerTest to use names by updating the test to:

    @Test
    public void testGetMapping() throws Exception {
      CoffeeOrderRepository coffeeOrderRepository = new FakeCoffeeOrderRepository();
      CoffeeOrder coffeeOrder = new CoffeeOrder();
      coffeeOrder.size(SizeOption.MEDIUM);
      coffeeOrder.changeNameTo("Ivan");
      coffeeOrder.setId(123L);
      coffeeOrderRepository.save(coffeeOrder);
    
      CoffeeOrderApiController controller = new CoffeeOrderApiController(coffeeOrderRepository);
    
      CoffeeOrderResponse coffeeOrderResponse = controller.coffeeOrderInfo("123");
    
      // medium coffee is 150 cents
      assertThat(coffeeOrderResponse.getPrice())
          .isEqualTo("150");
      assertThat(coffeeOrderResponse.getName())
         .isEqualTo("Ivan");
    }   
    
  4. This test should fail.

  5. Modify the CoffeeOrderResponse object to have a property (a String variable and its getter & setter) for name.

  6. Open the CoffeeOrderApiController class and in the coffeeOrderInfo method, copy the new name property from the CoffeeOrder to the CoffeeOrderResponse instance that is returned.

    • Copy the name to the response for the GET-mapped method (coffeeOrderInfo), too!
  7. The above test should now pass.

Add POST Method in the Controller

In this section, you'll create a new CoffeeOrder via an incoming POST request.

  1. Add a new method in the CoffeeOrderApiController that is mapped to a POST to the /api/coffeeorders endpoint:

    @PostMapping("/api/coffeeorders")
    public CoffeeOrderResponse createCoffeeOrder(@RequestBody CoffeeOrderCreateRequest request) {
    }
    
  2. In this method, create a new CoffeeOrder object, and update the properties with the ones that you get from the incoming request parameter. e.g.:

    CoffeeOrder coffeeOrder = new CoffeeOrder();
    coffeeOrder.changeNameTo(request.getName());
    coffeeOrder.size(SizeOption.valueOf(request.getSize()));
    // etc.
    
  3. Save this new CoffeeOrder instance in the CoffeeOrderRepository

  4. Take the newly saved coffee order and convert it into an CoffeeOrderReponse object and return it.

Try it out

Since you can't use a browser to do a POST to an API, you'll need to either use curl from the terminal, or you can use the Postman tool, with installation instructions here.

Using Postman

Do a POST with the following JSON data to the endpoint at localhost:8080/api/coffeeorders:

{"name":"Curly","size":"LARGE","creamer":"MILK","sweetener":"SUGAR"}

Using curl

curl -v --noproxy "*" -d '{"name":"Curly","size":"LARGE","creamer":"MILK","sweetener":"SUGAR"}' -H 'Content-Type: application/json' "localhost:8080/api/coffeeorders"

Browse

Now browse to do a get to see the order, e.g.:

http://localhost:8080/api/coffeeorders/2

Once you've completed the above steps,
check in with the instructor to review your code.