## What You Will Learn during this Step: - Create a REST Service for Retrieving all questions for a survey - Autowire SurveyService - Create @GetMapping("/surveys/{surveyId}/questions") - Use @PathVariable String surveyId - http://localhost:8080/surveys/Survey1/questions/ - How does the Bean get converted to a JSON? - Auto Configuration : If Jackson jar is on the class path, message converters are auto created! (Search in log :Creating shared instance of singleton bean 'mappingJackson2HttpMessageConverter') ## Some Theory - What is REST? - Architectural style for the web. REST specifies a set of constraints. - Client - Server : Server (service provider) should be different from a client (service consumer). - Enables loose coupling and independent evolution of server and client as new technologies emerge. - Each service should be stateless. - Each Resource has a resource identifier. - It should be possible to cache response. - Consumer of the service may not have a direct connection to the Service Provider. Response might be sent from a middle layer cache. - A resource can have multiple representations. Resource can modified through a message in any of the these representations. ## Useful Snippets and References - JSON View : https://jsonview.com/ First Snippet ``` @RestController class SurveyController { @Autowired private SurveyService surveyService; @GetMapping("/surveys/{surveyId}/questions") public List retrieveQuestions(@PathVariable String surveyId) { return surveyService.retrieveQuestions(surveyId); } } ``` ## Exercise - Try to think about how the URI for retrieving the details of a specific question should be! ## Files List ### pom.xml ``` 4.0.0 com.in28minutes.springboot first-springboot-project 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent 1.4.0.RELEASE 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-maven-plugin ``` ### src/main/java/com/in28minutes/springboot/Application.java ``` package com.in28minutes.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); } } ``` ### src/main/java/com/in28minutes/springboot/controller/SurveyController.java ``` package com.in28minutes.springboot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.in28minutes.springboot.model.Question; import com.in28minutes.springboot.service.SurveyService; @RestController class SurveyController { @Autowired private SurveyService surveyService; @GetMapping("/surveys/{surveyId}/questions") public List retrieveQuestions(@PathVariable String surveyId) { return surveyService.retrieveQuestions(surveyId); } } ``` ### src/main/java/com/in28minutes/springboot/model/Question.java ``` package com.in28minutes.springboot.model; import java.util.List; public class Question { private String id; private String description; private String correctAnswer; private List options; // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException: // Can not construct instance of com.in28minutes.springboot.model.Question: // no suitable constructor found, can not deserialize from Object value // (missing default constructor or creator, or perhaps need to add/enable // type information?) public Question() { } public Question(String id, String description, String correctAnswer, List options) { super(); this.id = id; this.description = description; this.correctAnswer = correctAnswer; this.options = options; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getDescription() { return description; } public String getCorrectAnswer() { return correctAnswer; } public List getOptions() { return options; } @Override public String toString() { return String .format("Question [id=%s, description=%s, correctAnswer=%s, options=%s]", id, description, correctAnswer, options); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Question other = (Question) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } } ``` ### src/main/java/com/in28minutes/springboot/model/Survey.java ``` package com.in28minutes.springboot.model; import java.util.List; public class Survey { private String id; private String title; private String description; private List questions; public Survey(String id, String title, String description, List questions) { super(); this.id = id; this.title = title; this.description = description; this.questions = questions; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public List getQuestions() { return questions; } public void setQuestions(List questions) { this.questions = questions; } @Override public String toString() { return "Survey [id=" + id + ", title=" + title + ", description=" + description + ", questions=" + questions + "]"; } } ``` ### src/main/java/com/in28minutes/springboot/service/SurveyService.java ``` package com.in28minutes.springboot.service; import java.math.BigInteger; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.springframework.stereotype.Component; import com.in28minutes.springboot.model.Question; import com.in28minutes.springboot.model.Survey; @Component public class SurveyService { private static List surveys = new ArrayList<>(); static { Question question1 = new Question("Question1", "Largest Country in the World", "Russia", Arrays.asList( "India", "Russia", "United States", "China")); Question question2 = new Question("Question2", "Most Populus Country in the World", "China", Arrays.asList( "India", "Russia", "United States", "China")); Question question3 = new Question("Question3", "Highest GDP in the World", "United States", Arrays.asList( "India", "Russia", "United States", "China")); Question question4 = new Question("Question4", "Second largest english speaking country", "India", Arrays .asList("India", "Russia", "United States", "China")); List questions = new ArrayList<>(Arrays.asList(question1, question2, question3, question4)); Survey survey = new Survey("Survey1", "My Favorite Survey", "Description of the Survey", questions); surveys.add(survey); } public List retrieveAllSurveys() { return surveys; } public Survey retrieveSurvey(String surveyId) { for (Survey survey : surveys) { if (survey.getId().equals(surveyId)) { return survey; } } return null; } public List retrieveQuestions(String surveyId) { Survey survey = retrieveSurvey(surveyId); if (survey == null) { return null; } return survey.getQuestions(); } public Question retrieveQuestion(String surveyId, String questionId) { Survey survey = retrieveSurvey(surveyId); if (survey == null) { return null; } for (Question question : survey.getQuestions()) { if (question.getId().equals(questionId)) { return question; } } return null; } private SecureRandom random = new SecureRandom(); public Question addQuestion(String surveyId, Question question) { Survey survey = retrieveSurvey(surveyId); if (survey == null) { return null; } String randomId = new BigInteger(130, random).toString(32); question.setId(randomId); survey.getQuestions().add(question); return question; } } ``` ### src/main/java/com/in28minutes/springboot/WelcomeController.java ``` package com.in28minutes.springboot; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class WelcomeController { //Auto wiring @Autowired private WelcomeService service; @RequestMapping("/welcome") public String welcome() { return service.retrieveWelcomeMessage(); } } ``` ### src/main/java/com/in28minutes/springboot/WelcomeService.java ``` package com.in28minutes.springboot; import org.springframework.stereotype.Component; @Component public class WelcomeService { public String retrieveWelcomeMessage() { //Complex Method return "Good Morning updated"; } } ``` ### src/main/resources/application.properties ``` logging.level.org.springframework: DEBUG ```