Codes should be copied into the word documents. IntelliJ IDE to be used
Topics Covered: · REST APIs · HTTP Requests · URLs and Parameters This assessment will assess your mastery of the following Learning Outcomes: · You will be able to understand the difference between a client and a server · You will be able to construct a URL with query parameters · You will be able to use an API's documentation to determine how to interact with the API · You will be able to retrieve data from an API · You will be able to send data to an API · You will be able to write code that is organized, easily understood, and free of errors Assignment Open the activity and clone it to your computer. You will be creating methods to call the BoredAPI service which randomly suggests activities. Read the documentation here BoredAPI Step One - Generate a random activity and build the DTO 1. Using Postman or a web browser, test sending a GET request to the endpoint: http://www.boredapi.com/api/activity 2. You will get a JSON response that looks like the sample below. { "activity": "Start a garden", "type": "recreational", "participants": 1, "price": 0.3, "link": "", "key": "1934228", "accessibility": 0.35} 3. Use the JSON response to create a class in ActivityDTO.java to hold the object. (You can do this either by hand or by using the DTO generator). IMPORTANT: When using the generator, you will need to check that the generator picked up the appropriate data types. Make sure that price and accessibility are changed to use datatype double in ActivityDTO.java in the variable declarations and the getter/setter methods. If these two properties are set to int, you will lose the precision after the decimal .. Also, make sure you remove the keyword abstract from the class if it was added to ActivityDTO.java by the generator Step Two - Format the URL You will write two versions of the formatURL() method. One takes in one parameter and value and returns the formatted URL. This is called overloading the method. The first version takes a URLString, parameter and value and returns a URL query with one parameter and value. The second version takes a URLString and two sets of properties and values (parameter1 and value1, parameter2 and value2). This version returns the URL query with two parameters and values. Hint: The ampersand & is used to combine multiple queries in one string. The method signatures have been provided in Main.java: /* Initialize the required constant variable here */ static final String GET_URL = ""; //Formats URL query string with one property public static String formatURL(String URLString, String property, String value){ //TODO: Fill out method and update return value return ""; } //Overload method: Formats URL query string with two properties public static String formatURL(String URLString, String property1, String value1,String property2, String value2){ //TODO: Fill out method and update return value return ""; } Sample calls: Where GET_URL is set to the base URL of the API. String URLString1 = formatURL(GET_URL, "type", "education"); //returns "http://www.boredapi.com/api/activity?type=education" String URLString2 = formatURL(GET_URL,"type","education","price","0.0"); //returns "http://www.boredapi.com/api/activity?type=education&price=0.0" Step Three - Code the basic HTTP call Write two helper functions: 1. Write a static method String getURLResponse(String URLString) in Main.java that takes a URL and does an HTTP GET and returns the JSON response if successful. Any potential exceptions should be declared using throws so they can be handled upstream. The return values are the exact strings returned from the HTTP requests. This method does not format. Example return values for `getURLResponse()` : ```{ "activity": "Learn a new programming language", "accessibility": 0.25, "type": "education", "participants": 1, "price": 0.1, "key": "5881028" }``````{ "error": "No activity found with the specified parameters"}``` 2. Write a static method formatActivityOutput(String jsonString) in the Main.java class that will take a JSON response and use the Jackson API to parse out and return a String in the following format: In the case of any exception or if the jsonString entered is the "No activity found" error message, then return the message: "No activity found" Example return values for formatActivityOutput(): Successful return: Activity: Make a budgetType: busyworkParticipants: 1Price: 0.1 If the JSON response was empty or contained an error message: No activity found Step Four - Create Additional API calls These methods will combine the methods from the previous steps. First, review the BoredAPI documentation and use Postman or your web browser to determine the URLs required to make the following queries: · Return an activity of specific type such as recreational. · Return an activity of a specific price. For example where price is equal to 0.0. · Return an activity of a type AND a number of participants. This URL is taking the combination of two parameters. Once you have found the correct URL and queries to use, write the methods to execute the same queries. Each method should return the full JSON String. Example: For endpoint: https://www.boredapi.com/api/activity?type=music Response: { "activity": "Make a simple musical instrument", "type": "music", "participants": 1, "price": 0.4, "link": "", "key": "7091374", "accessibility": 0.25} Method: getActivityRandom(String URL) · String URL - the URL of the request including query parameters and values. Method: getActivityType(String URL, String type) · String URL - the URL of the request including query parameters and values. · String type - the parameter name. i.e. "type", "price", " Method: getActivityWithPrice(String URL, double price) · String URL - the URL of the request including query parameters and values. · double price - the price of the activity. Method: getActivityTypeForGroup(String URL, String type, int numParticipants) · String URL - the URL of the request including query parameters and values. · String type - the type of activity. i.e. "recreational" · int numParticipants - the number of partipants to search on How do you know if your code works? Unit tests for the methods have been included in MainTest.java. Make sure all of the tests pass. Example output from main(): Your output will vary because the activities are generated randomly. IDE (IntelliJ) Codes Main.Java Codes package com.kenzie.app; import com.fasterxml.jackson.databind.ObjectMapper; import java.net.URI; import java.io.IOException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class Main { // Initialize the required constant variable here static final String GET_URL = ""; //Formats URL query string with one property public static String formatURL(String URLString, String parameter, String value){ //TODO: Fill out method and update return value return ""; } //Overload method: Formats URL query string with two properties public static String formatURL(String URLString, String parameter1, String value1,String parameter2, String value2){ //TODO: Fill out method and update return value return ""; } public static String getURLResponse(String URLString) { //TODO: Fill out method and update return value return ""; } public static String formatActivityOutput(String jsonString){ //TODO: Fill out method and update return value return ""; } public static String getActivityRandom(String URL) { //TODO: Fill out method and update return value return ""; } public static String getActivityType(String URL, String type) throws com.fasterxml.jackson.core.JsonProcessingException,IOException{ //TODO: Fill out method and update return value return ""; } public static String getActivityWithPrice(String URL, double price) throws com.fasterxml.jackson.core.JsonProcessingException,IOException{ //TODO: Fill out method and update return value return ""; } public static String getActivityTypeForGroup(String URL, String type, int numParticipants) { //TODO: Fill out method and update return value return ""; } /** Do not modify main method **/ public static void main(String[] args) throws IOException { String response; try { System.out.println("Are you feeling bored? Try these activities: "); //parse JSON string into formatted output System.out.println(formatActivityOutput(getActivityRandom(GET_URL))); System.out.println(formatActivityOutput(getActivityType(GET_URL, "education"))); System.out.println(formatActivityOutput(getActivityWithPrice(GET_URL, 0))); System.out.println(formatActivityOutput(getActivityTypeForGroup(GET_URL, "recreational",4))); //Test for error checking: this last one does not have a return. Should print "No activity found" System.out.println(formatActivityOutput(getActivityType(GET_URL, "mayhem"))); } catch (Exception e) { System.out.println(e.getMessage()); } } } ActivityDTO.java code package com.kenzie.app; import com.fasterxml.jackson.annotation.JsonPropertyOrder; public class ActivityDTO { } MainTest.Java package com.kenzie.app; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.databind.SerializationFeature; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.*; import java.io.IOException; import java.lang.reflect.*; public class MainTest { private MockWebServer mockWebServer; public static final String TEST_ENDPOINT = "http://www.boredapi.com/api/activity"; public static final String TEST_ACTIVITY = "Try a food you don't like"; public static final String TEST_TYPE = "social"; public static final String TEST_KEY = "6693574"; public static final String TEST_TYPE_TWO = "recreational"; public static final String TEST_KEY_TWO = "6693575"; public static final String TEST_LINK = "http://www.w3schools.com/java/"; public static final String TEST_KEY_RESPONSE = "{\"activity\":\"Try a food you don't like\",\"type\":\"recreational\",\"participants\":1,\"price\":0.1,\"link\":\"\",\"key\":\"6693574\",\"accessibility\":0.05}"; public static final String TEST_FORMAT_URL = "http://www.boredapi.com/api/activity?social=6693574"; public static final String TEST_FORMAT_URL_TWO = "http://www.boredapi.com/api/activity?social=6693574&recreational=6693575"; public static final double TEST_PRICE = 0.1; public static final double TEST_ACCESSIBILITY = 1.0; public static final int TEST_PARTICIPANTS = 1; public static final String TEST_FORMATTED_ACTIVITY = "Activity: Try a food you don't like\n" + "Type: recreational\n" + "Participants: 1\n" + "Price: 0.1\n"; @BeforeEach void init() throws IOException { this.mockWebServer = new MockWebServer(); this.mockWebServer.start(); } @Test void canCreateActivity() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { try{ //check that required methods are defined ActivityDTO activityInstance = new ActivityDTO(); Method setActivityMethod = ActivityDTO.class.getMethod("setActivity",String.class); setActivityMethod.invoke(activityInstance, TEST_ACTIVITY); Method setTypeMethod = ActivityDTO.class.getMethod("setType",String.class); setTypeMethod.invoke(activityInstance, TEST_TYPE); Method setKeyMethod = ActivityDTO.class.getMethod("setKey",String.class); setKeyMethod.invoke(activityInstance, TEST_KEY); Method setLinkMethod = ActivityDTO.class.getMethod("setLink",String.class); setLinkMethod.invoke(activityInstance, TEST_LINK); Method setParticipantsMethod = ActivityDTO.class.getMethod("setParticipants",int.class); setParticipantsMethod.invoke(activityInstance, TEST_PARTICIPANTS); Method setAccessibilityMethod = ActivityDTO.class.getMethod("setAccessibility",double.class); setAccessibilityMethod.invoke(activityInstance, TEST_ACCESSIBILITY); Method setPriceMethod = ActivityDTO.class.getMethod("setPrice",double.class);