Building Lightweight Web Services with Spring Boot and Spring WebMVC
Web service implementation forms the core of most Spring Boot application development, as nearly all modern internet-facing apps expose HTTP-based endpoints for external interaction. Spring Boot delivers multiple options for building lightweight web services, starting with Spring WebMVC—a classic Model-View-Controller (MVC) framework component that lets developers build RESTful endpoints with core annotations, plus RestTemplate for service consumption. For higher REST maturity, Spring HATEOAS enables hypermedia-driven, self-descriptive APIs. For decoupled frontends, Spring GraphQL provides a graph-based query language to tailor data shape, reduce round-trips, and endpoints.
Spring WebMVC builds on the MVC architecture to enable flexible, loosely-coupled HTTP endpoints, natively included in the Spring Framework and fully integrated with Spring Boot. Web service work splits into creation and consumption, covered below.
Creating HTTP Controllers
Spring Boot simplifeis controller implementation centers on building controller classes to handle requests and return structured responses.
Define a REST Controller
@RestController
@RequestMapping(path = "/persons", produces = MediaType.APPLICATION_JSON_VALUE)
public class PersonController {
@GetMapping("/{personId}")
public Person fetchPersonById(@PathVariable String personId) {
Person mockPerson = new Person();
mockPerson.setId(personId);
mockPerson.setFullName("李四");
return mockPerson;
}
}
Domain Model
@Document("persons")
public class Person {
@Id
private String id;
@Field("full_name")
private String fullName;
@Field("years_old")
private Integer yearsOld;
@Field("created_ts")
private Date createdTimestamp;
@Field("citizenship")
private String citizenship;
@Field("friend_ids")
private List<String> friendIdentifiers;
@Field("post_ids")
private List<String> postIdentifiers;
// Getters and Setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getFullName() { return fullName; }
public void setFullName(String fullName) { this.fullName = fullName; }
public Integer getYearsOld() { return yearsOld; }
public void setYearsOld(Integer yearsOld) { this.yearsOld = yearsOld; }
public Date getCreatedTimestamp() { return createdTimestamp; }
public void setCreatedTimestamp(Date createdTimestamp) { this.createdTimestamp = createdTimestamp; }
public String getCitizenship() { return citizenship; }
public void setCitizenship(String citizenship) { this.citizenship = citizenship; }
public List<String> getFriendIdentifiers() { return friendIdentifiers; }
public void setFriendIdentifiers(List<String> friendIdentifiers) { this.friendIdentifiers = friendIdentifiers; }
public List<String> getPostIdentifiers() { return postIdentifiers; }
public void setPostIdentifiers(List<String> postIdentifiers) { this.postIdentifiers = postIdentifiers; }
}
@RestController combines @Controller and @ResponseBody, automatically serializing/deserializing request/resposne bodies to JSON, eliminating manual view rendering setup for REST endpoints. Spring Boot 2+ adds expllicit HTTP method annotations like @GetMapping, @PostMapping, @PutMapping, @DeleteMapping as shorthand for @RequestMapping with fixed method values. The example uses a class-level @RequestMapping to set a base path, with method-level mappings refining endpoint details.
Processing Web Request Handling
Extracting input and structuring responses uses Spring Boot’s request mapping annotations for streamlined input control, including @PathVariable and @RequestBody.
@PathVariable pulls values from URI path segments (e.g., /persons/{personId}), as shown earlier. Below is a dual-path-variable example:
@PostMapping("/{displayName}/{accessKey}")
public Person initializePerson(@PathVariable("displayName") String displayName, @PathVariable("accessKey") String accessKey) {
Person newPerson = new Person();
newPerson.setFullName(displayName);
return newPerson;
}
The produces attribute in @RequestMapping sets the response Content-Type header, standardized here to application/json via MediaType.APPLICATION_JSON_VALUE for type safety.
For JSON request bodies with Content-Type: application/json, @RequestBody binds incoming JSON directly to a domain object, replacing path variables for complex inputs:
@PostMapping("/")
public Person createPerson(@RequestBody Person incomingPerson) {
incomingPerson.setCreatedTimestamp(new Date());
return incomingPerson;
}
Consuming Web Services
Spring Boot provides RestTemplate as a template utility for synchronous HTTP service consumption.
Register RestTemplate Bean
Inject a RestTemplate instance into the Spring container via a configuration class for shared reuse:
@Configuration
public class RestClientConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
This bean can be autowired anywhere in the application. RestTemplate offers a suite of pre-built methods for sending HTTP requests, all defaulting to JSON serialization/deserialization for request/response bodies.