How to retrieve a resource (object) with GET METHOD in REST API by using date as a @PathParam in Quarkus

668 Views Asked by At

I am new to programming and I am trying to build a small dietary tracking app. I use quarkus RESTeasy JAX-RS and java to build my REST API. The user should be able to add foods he ate in days of the week.

The user must be able to retrieve the foods he ate based on the date. My issue is that I can't retrieve the food based on the date. When I use the Timestamp: "2021-06-10T08:44:45.9328079Z[UTC]" as the input date on my end point for GET Method, I get 400 BAD REQUEST in postman. When I retrieve foods based on userId it works fine.

Here is my code with the GET and POST methods:

@Path("/foods") public class Controller {

public static ArrayList<Object> foods = new ArrayList<>();

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllFood(){
    return Response.ok(foods).build();
}

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response addFood() throws ParseException {

    foods.add(new Food("Garlic", 30, Timestamp.from(Instant.now()), 1));
    foods.add(new Food("Onions", 20, Timestamp.from(Instant.now()), 2));
    return Response.ok(foods).build();

}

@Path("{userId}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public static Response getFoodById(@PathParam("userId") int userId){
    for (Object food : foods){
        if (((Food)food).getUserId()==(userId)){
            return Response.ok(food).build();
        }
    }
    return null;
}

@Path("/second/{time}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getFoodByDate(@PathParam("time") Timestamp time){
    for (Object food : foods){
        if (((Food)food).getTime().toString().equals(time.toString())){
            return Response.ok(food).build();
        }
    }
    return null;
}

}

And here is the Food Class:

package org.acme;

import java.sql.Timestamp;

public class Food {

private String foodType;
private int portion;
private Timestamp time;
private int userId;

public Food(){}

public Food(String foodType, int portion, Timestamp time, int userId){
    this.foodType = foodType;
    this.portion = portion;
    this.time = time;
    this.userId = userId;

}

public String getFoodType() {
    return foodType;
}

public void setFoodType(String foodType) {
    this.foodType = foodType;
}

public int getPortion() {
    return portion;
}

public void setPortion(int portion) {
    this.portion = portion;
}

public Timestamp getTime() {
    return time;
}

public void setTime(Timestamp time) {
    this.time = time;
}

public int getUserId() {
    return userId;
}

public void setUserId(int userId) {
    this.userId = userId;
}

@Override
public String toString(){
    return foodType + ", " + portion + ", " + time + ", " + userId;
}

}

1

There are 1 best solutions below

0
On BEST ANSWER

Ok - the reason why the error thrown from Postman is 400 bad request is due to your input parameter is incorrect.

Sample code with a change from the @PathParam to @RequestParam

@Path("/get/second/")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getFoodByDate(@RequestParam("time") String dateString) throws ParseException{
   ArrayList<Food> foods = new ArrayList<>();
   DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

   Date requestedDate = sdf.parse(dateString);
   for (Object food : foods){
       if (((Food)food).getTime().equals(requestedDate)){
           return Response.ok(food).build();
       }
   }

   return null;
}

In this example, I changed your timestamp parameter as java.sql.Timestamp is thin wrapper around java.util.Date that allows the JDBC API to identify this as an SQL TIMESTAMP value, hence in this example it is not suggested to use timestamp.

Sample refactored Food class.

public class Food {
    private String foodType;
    private int portion;
    private Date time;
    private int userId;

    public Food(){}

    public Food(String foodType, int portion, Date time, int userId){
        this.foodType = foodType;
        this.portion = portion;
        this.time = time;
        this.userId = userId;

    } ... //getter and setter

Sample code to add food to your array list.

    DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Food food1 = new Food("Garlic", 10, sdf.parse("2020-05-01"), 1);
    Food food2 = new Food("Onion", 20, sdf.parse("2020-05-02"), 1);
    Food food3 = new Food("Potato", 30, sdf.parse("2020-05-03"), 1);
    Food food4 = new Food("Tomato", 40, sdf.parse("2020-05-04"), 1);

    ArrayList<Food> foods = new ArrayList<>();
    foods.add(food1);
    foods.add(food2);
    foods.add(food3);
    foods.add(food4);

Full source code I tested against:

package org.example;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class Main {

    public static void main(String[] args) throws ParseException {

        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = "2020-05-01"; //mocking request date from the @RequestParam
        Date requestedDate = sdf.parse(dateString);

        
        Food food1 = new Food("Garlic", 10, sdf.parse("2020-05-01"), 1);
        Food food2 = new Food("Onion", 20, sdf.parse("2020-05-02"), 1);
        Food food3 = new Food("Potato", 30, sdf.parse("2020-05-03"), 1);
        Food food4 = new Food("Tomato", 40, sdf.parse("2020-05-04"), 1);

        ArrayList<Food> foods = new ArrayList<>();
        foods.add(food1);
        foods.add(food2);
        foods.add(food3);
        foods.add(food4);
        
        for (Object food : foods){
            if (((Food)food).getTime().equals(requestedDate)){
                System.out.print(food);
            }
        }

    }
}

Output: Garlic, 10, Fri May 01 00:00:00 SGT 2020, 1