SlideShare a Scribd company logo
1 of 31
Download to read offline
Confidential │ ©2020 VMware, Inc.
Introduction to
WebMvc.fn
Functional Servlet Endpoints
Arjen Poutsma (@poutsma)
Sr. Staff Engineer at VMware
3rd September 2020
Confidential │ ©2020 VMware, Inc.
Agenda
2
Handler Functions
Router Functions
Filter Functions
Final Comparison
Confidential │ ©2020 VMware, Inc. 3
WebMvc.fn was introduced
in Spring 5.2 and is fully
compatible with Spring Boot
Confidential │ ©2020 VMware, Inc.
Handler Functions
Map from ServerRequest to ServerResponse
4
Confidential │ ©2020 VMware, Inc. 5
Map from ServerRequest to ServerResponse
Handler Functions
@Controller
class PersonController {
PersonRepository repository;
ResponseEntity<Person> getPerson(@PathVariable String id) {
Person person = repository.findById(id);
return ResponseEntity.ok()
.contentType(APPLICATION_JSON)
.body(person);
}
ResponseEntity<List<Person>> getPeople() {
List<Person> people = repository.findAll();
return ResponseEntity.ok()
.contentType(APPLICATION_JSON)
.body(people);
}
}
Web MVC
Confidential │ ©2020 VMware, Inc. 5
Map from ServerRequest to ServerResponse
Handler Functions
@Controller
class PersonHandler {
PersonRepository repository;
ServerResponse getPerson(ServerRequest request) {
String id = request.pathVariable("id");
Person person = repository.findById(id);
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(person);
}
ServerResponse getPeople(ServerRequest request) {
List<Person> people = repository.findAll();
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(people);
}
}
WebMvc.fn
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
6
Handler Function Comparison
@Controller
class PersonController {
PersonRepository repository;
ResponseEntity<Person> getPerson(@PathVariable String id) {
Person person = repository.findById(id);
return ResponseEntity.ok()
.contentType(APPLICATION_JSON)
.body(person);
}
ResponseEntity<List<Person>> getPeople() {
List<Person> people = repository.findAll();
return ResponseEntity.ok()
.contentType(APPLICATION_JSON)
.body(people);
}
}
@Controller
class PersonHandler {
PersonRepository repository;
ServerResponse getPerson(ServerRequest request) {
String id = request.pathVariable("id");
Person person = repository.findById(id);
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(person);
}
ServerResponse getPeople(ServerRequest request) {
List<Person> people = repository.findAll();
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(people);
}
}
Confidential │ ©2020 VMware, Inc. 7
Handler Functions map from
ServerRequest to ServerResponse
• both are immutable
• create response with builder
Confidential │ ©2020 VMware, Inc.
Router Functions
Map from ServerRequest to HandlerFunction
8
Confidential │ ©2020 VMware, Inc. 9
Map from ServerRequest to HandlerFunction
Router Functions
@Controller
@RequestMapping("/people")
class PersonController {
PersonRepository repository;
@RequestMapping(value = "/{id}", method = GET)
ResponseEntity<Person> getPerson(@PathVariable String id) {
...
}
@RequestMapping(method = GET)
ResponseEntity<List<Person>> getPeople() {
...
}
}
Web MVC
Confidential │ ©2020 VMware, Inc. 9
Map from ServerRequest to HandlerFunction
Router Functions
@Controller
class PersonHandler {
PersonRepository repository;
ServerResponse getPerson(ServerRequest request) {
...
}
ServerResponse getPeople(ServerRequest request) {
...
}
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.GET("/people/{id}", handler::getPerson)
.GET(“/people", handler::getPeople)
.build();
}
}
WebMvc.fn
Confidential │ ©2020 VMware, Inc. 9
Map from ServerRequest to HandlerFunction
Router Functions
@Controller
class PersonHandler {
PersonRepository repository;
ServerResponse getPerson(ServerRequest request) {
...
}
ServerResponse getPeople(ServerRequest request) {
...
}
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.path(“/people", builder -> builder
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople));
.build();
}
}
WebMvc.fn
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
10
Router Function Comparison
@Controller
class PersonHandler {
PersonRepository repository;
ServerResponse getPerson(ServerRequest request) {
...
}
ServerResponse getPeople(ServerRequest request) {
...
}
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.path(“/people", builder -> builder
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople));
.build();
}
}
@Controller
@RequestMapping(“/people")
class PersonController {
PersonRepository repository;
@RequestMapping(value = "/{id}", method = GET)
ResponseEntity<Person> getPerson(@PathVariable String id) {
...
}
@RequestMapping(method = GET)
ResponseEntity<List<Person>> getPeople() {
...
}
}
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
10
Router Function Comparison
@Controller
class PersonHandler {
PersonRepository repository;
ServerResponse getPerson(ServerRequest request) {
...
}
ServerResponse getPeople(ServerRequest request) {
...
}
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.path(“/people", builder -> builder
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople));
.build();
}
}
@Controller
@RequestMapping(“/people")
class PersonController {
PersonRepository repository;
@RequestMapping(value = "/{id}", method = GET)
ResponseEntity<Person> getPerson(@PathVariable String id) {
...
}
@RequestMapping(method = GET)
ResponseEntity<List<Person>> getPeople() {
...
}
}
Confidential │ ©2020 VMware, Inc. 11
Router Functions created using builder
• GET, POST, PUT, etc.
• resources
• nesting
• more powerful abstraction underneath:
RequestPredicate
Confidential │ ©2020 VMware, Inc.
Request Predicates
Evaluate on a ServerRequest
12
Confidential │ ©2020 VMware, Inc. 13
Evaluate on a ServerRequest
Request Predicates
RequestPredicate get = RequestPredicates.method(HttpMethod.GET);
RequestPredicate people = RequestPredicates.path("/people");
RequestPredicate getPeople = get.and(people); // or RequestPredicates.GET("/people")
RequestPredicate acceptJson = RequestPredicates.accept(APPLICATION_JSON);
RequestPredicate extensionJson = RequestPredicates.pathExtension("json");
RequestPredicate paramTypeJson = RequestPredicates.param("type", "json");
RequestPredicate json = acceptJson.or(extensionJson).or(paramTypeJson);
Confidential │ ©2020 VMware, Inc. 14
Evaluate on a ServerRequest
Request Predicates
@Controller
class PersonHandler {
PersonRepository repository;
...
ServerResponse createPerson(ServerRequest request) {
Person person = request.body(Person.class);
repository.savePerson(person);
return ServerResponse.ok()
.build();
}
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.path("/people", b -> b
.GET("/{id}", accept(APPLICATION_JSON), handler::getPerson)
.GET("/", accept(APPLICATION_JSON), handler::getPeople)
.POST("/", contentType(APPLICATION_JSON), handler::createPerson))
.build();
}
}
Confidential │ ©2020 VMware, Inc. 14
Evaluate on a ServerRequest
Request Predicates
@Controller
class PersonHandler {
PersonRepository repository;
...
ServerResponse createPerson(ServerRequest request) {
Person person = request.body(Person.class);
this.repository.savePerson(person);
return ServerResponse.ok()
.build();
}
@Bean
static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) {
return route()
.path(“/people", b -> b
.nest(accept(APPLICATION_JSON), b1 -> b1
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople)
)
.POST("/", contentType(APPLICATION_JSON), handler::createPerson))
.build();
}
}
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
15
Request Predicates Comparison
@Controller
@RequestMapping(“/people”)
class PersonController {
PersonRepository repository;
@RequestMapping(value = "/{id}",
method = GET,
produces = APPLICATION_JSON_VALUE)
ResponseEntity<Person> getPerson(@PathVariable String id) {
...
}
@RequestMapping(method = GET,
produces = APPLICATION_JSON_VALUE)
ResponseEntity<List<Person>> showPeople() {
...
}
@RequestMapping(method = POST,
consumes = APPLICATION_JSON_VALUE)
void createPerson(RequestEntity<Person> person) {
...
}
}
@Controller
class PersonHandler {
PersonRepository repository;
...
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.path(“/people", b -> b
.GET("/{id}", accept(APPLICATION_JSON), handler::getP
.GET("/", accept(APPLICATION_JSON), handler::getPeopl
.POST("/", contentType(APPLICATION_JSON), handler::cr
.build();
}
}
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
15
Request Predicates Comparison
@Controller
@RequestMapping(“/people”)
class PersonController {
PersonRepository repository;
@RequestMapping(value = "/{id}",
method = GET,
produces = APPLICATION_JSON_VALUE)
ResponseEntity<Person> getPerson(@PathVariable String id) {
...
}
@RequestMapping(method = GET,
produces = APPLICATION_JSON_VALUE)
ResponseEntity<List<Person>> showPeople() {
...
}
@RequestMapping(method = POST,
consumes = APPLICATION_JSON_VALUE)
void createPerson(RequestEntity<Person> person) {
...
}
}
@Controller
class PersonHandler {
PersonRepository repository;
...
@Bean
static RouterFunction router(PersonHandler handler) {
return route()
.path(“/people", b -> b
.GET("/{id}", accept(APPLICATION_JSON), handler::getP
.GET("/", accept(APPLICATION_JSON), handler::getPeopl
.POST("/", contentType(APPLICATION_JSON), handler::cr
.build();
}
}
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
16
Request Predicates Comparison
@Controller
class PersonHandler {
PersonRepository repository;
...
@Bean
static RouterFunction<ServerResponse> routerFunction(Person
return route()
.path("/person", b -> b
.nest(accept(APPLICATION_JSON), b1 -> b1
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople)
)
.POST("/", contentType(APPLICATION_JSON), handler::cr
.build();
}
}
?
Confidential │ ©2020 VMware, Inc.
Handler Filter Functions
Maps ServerRequest and HandlerFunction
to ServerResponse
17
Confidential │ ©2020 VMware, Inc. 18
Maps ServerRequest and HandlerFunction to ServerResponse
Handler Filter Functions
@Controller
@RequestMapping("/people")
class PersonController {
PersonRepository repository;
...
@ExceptionHandler(NotFoundException.class)
ResponseEntity notFound() {
return ResponseEntity.notFound().build()
}
}
Web MVC
Confidential │ ©2020 VMware, Inc. 18
Maps ServerRequest and HandlerFunction to ServerResponse
Handler Filter Functions
@Controller
class PersonHandler {
PersonRepository repository;
...
ServerResponse notFound(Throwable throwable, ServerRequest request) {
return ServerResponse.notFound().build();
}
@Bean
static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) {
return route()
.path(“/people", b -> b
.nest(accept(APPLICATION_JSON), b1 -> b1
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople)
)
.POST("/", contentType(APPLICATION_JSON), handler::createPerson))
.onError(NotFoundException.class, handler::notFound)
.build();
}
}
WebMvc.fn
Confidential │ ©2020 VMware, Inc. 18
Maps ServerRequest and HandlerFunction to ServerResponse
Handler Filter Functions
@Controller
class PersonHandler {
PersonRepository repository;
...
ServerResponse notFound(Throwable throwable, ServerRequest request) {
return ServerResponse.notFound().build();
}
@Bean
static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) {
return route()
.path(“/people", b -> b
.nest(accept(APPLICATION_JSON), b1 -> b1
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople)
.onError(NotFoundException.class, handler::notFound)
)
.POST("/", contentType(APPLICATION_JSON), handler::createPerson))
.build();
}
}
WebMvc.fn
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
19
Handler Filter Function Comparison
@Controller
@RequestMapping("/people")
class PersonController {
PersonRepository repository;
...
@ExceptionHandler(NotFoundException.class)
ResponseEntity notFound() {
return ResponseEntity.notFound().build()
}
}
@Controller
class PersonHandler {
PersonRepository repository;
...
ServerResponse notFound(Throwable throwable, ServerRequest request) {
return ServerResponse.notFound().build();
}
@Bean
static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) {
return route()
.path("/person", b -> b
.nest(accept(APPLICATION_JSON), b1 -> b1
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople)
)
.POST("/", contentType(APPLICATION_JSON), handler::createPerson))
.onError(NotFoundException.class, handler::notFound)
.build();
}
}
Confidential │ ©2020 VMware, Inc.
Web MVC WebMvc.fn
19
Handler Filter Function Comparison
@Controller
@RequestMapping("/people")
class PersonController {
PersonRepository repository;
...
@ExceptionHandler(NotFoundException.class)
ResponseEntity notFound() {
return ResponseEntity.notFound().build()
}
}
@Controller
class PersonHandler {
PersonRepository repository;
...
ServerResponse notFound(Throwable throwable, ServerRequest request) {
return ServerResponse.notFound().build();
}
@Bean
static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) {
return route()
.path("/person", b -> b
.nest(accept(APPLICATION_JSON), b1 -> b1
.GET("/{id}", handler::getPerson)
.GET("/", handler::getPeople)
)
.POST("/", contentType(APPLICATION_JSON), handler::createPerson))
.onError(NotFoundException.class, handler::notFound)
.build();
}
}
Confidential │ ©2020 VMware, Inc.
Final Comparison
20
Confidential │ ©2020 VMware, Inc.
• Functions
• Code
• Rigid handler methods
(ServerRequest→ServerResponse)
• Flexible routing
• Annotations
• Meta-data
• Flexible handler methods
(parameters & return type)
• Limited routing
Web MVC WebMvc.fn
21
Request Predicates Comparison
Confidential │ ©2020 VMware, Inc.
Thank You

More Related Content

What's hot

Java springboot microservice - Accenture Technology Meetup
Java springboot microservice - Accenture Technology MeetupJava springboot microservice - Accenture Technology Meetup
Java springboot microservice - Accenture Technology MeetupAccenture Hungary
 
Spring Up Your Graph
Spring Up Your GraphSpring Up Your Graph
Spring Up Your GraphVMware Tanzu
 
Spring Boot Loves K8s
Spring Boot Loves K8sSpring Boot Loves K8s
Spring Boot Loves K8sVMware Tanzu
 
Walking Through Spring Cloud Data Flow
Walking Through Spring Cloud Data FlowWalking Through Spring Cloud Data Flow
Walking Through Spring Cloud Data FlowVMware Tanzu
 
Going Serverless Using the Spring Framework Ecosystem
Going Serverless Using the Spring Framework EcosystemGoing Serverless Using the Spring Framework Ecosystem
Going Serverless Using the Spring Framework EcosystemVMware Tanzu
 
Cloud Foundry for Spring Developers
Cloud Foundry for Spring DevelopersCloud Foundry for Spring Developers
Cloud Foundry for Spring DevelopersGunnar Hillert
 
Spring Native and Spring AOT
Spring Native and Spring AOTSpring Native and Spring AOT
Spring Native and Spring AOTVMware Tanzu
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudEberhard Wolff
 
Weaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping TechnologiesWeaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping TechnologiesVMware Tanzu
 
Ingress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway APIIngress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway APIVMware Tanzu
 
Spring Data JDBC: Beyond the Obvious
Spring Data JDBC: Beyond the ObviousSpring Data JDBC: Beyond the Obvious
Spring Data JDBC: Beyond the ObviousVMware Tanzu
 
Micronaut: Changing the Micro Future
Micronaut: Changing the Micro FutureMicronaut: Changing the Micro Future
Micronaut: Changing the Micro FutureZachary Klein
 
Spring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWSSpring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWSVMware Tanzu
 
Simplify Cloud Applications using Spring Cloud
Simplify Cloud Applications using Spring CloudSimplify Cloud Applications using Spring Cloud
Simplify Cloud Applications using Spring CloudRamnivas Laddad
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud VMware Tanzu
 
Peering Inside the Black Box: A Case for Observability
Peering Inside the Black Box: A Case for ObservabilityPeering Inside the Black Box: A Case for Observability
Peering Inside the Black Box: A Case for ObservabilityVMware Tanzu
 
From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0VMware Tanzu
 
Game of Streams: How to Tame and Get the Most from Your Messaging Platforms
Game of Streams: How to Tame and Get the Most from Your Messaging PlatformsGame of Streams: How to Tame and Get the Most from Your Messaging Platforms
Game of Streams: How to Tame and Get the Most from Your Messaging PlatformsVMware Tanzu
 

What's hot (20)

Java springboot microservice - Accenture Technology Meetup
Java springboot microservice - Accenture Technology MeetupJava springboot microservice - Accenture Technology Meetup
Java springboot microservice - Accenture Technology Meetup
 
Spring Up Your Graph
Spring Up Your GraphSpring Up Your Graph
Spring Up Your Graph
 
Spring Boot Loves K8s
Spring Boot Loves K8sSpring Boot Loves K8s
Spring Boot Loves K8s
 
Walking Through Spring Cloud Data Flow
Walking Through Spring Cloud Data FlowWalking Through Spring Cloud Data Flow
Walking Through Spring Cloud Data Flow
 
Going Serverless Using the Spring Framework Ecosystem
Going Serverless Using the Spring Framework EcosystemGoing Serverless Using the Spring Framework Ecosystem
Going Serverless Using the Spring Framework Ecosystem
 
Cloud Foundry for Spring Developers
Cloud Foundry for Spring DevelopersCloud Foundry for Spring Developers
Cloud Foundry for Spring Developers
 
Springboot Microservices
Springboot MicroservicesSpringboot Microservices
Springboot Microservices
 
Spring Native and Spring AOT
Spring Native and Spring AOTSpring Native and Spring AOT
Spring Native and Spring AOT
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
 
Weaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping TechnologiesWeaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
 
Ingress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway APIIngress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway API
 
Spring Data JDBC: Beyond the Obvious
Spring Data JDBC: Beyond the ObviousSpring Data JDBC: Beyond the Obvious
Spring Data JDBC: Beyond the Obvious
 
Micronaut: Changing the Micro Future
Micronaut: Changing the Micro FutureMicronaut: Changing the Micro Future
Micronaut: Changing the Micro Future
 
Spring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWSSpring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWS
 
Simplify Cloud Applications using Spring Cloud
Simplify Cloud Applications using Spring CloudSimplify Cloud Applications using Spring Cloud
Simplify Cloud Applications using Spring Cloud
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud
 
Peering Inside the Black Box: A Case for Observability
Peering Inside the Black Box: A Case for ObservabilityPeering Inside the Black Box: A Case for Observability
Peering Inside the Black Box: A Case for Observability
 
From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0
 
Game of Streams: How to Tame and Get the Most from Your Messaging Platforms
Game of Streams: How to Tame and Get the Most from Your Messaging PlatformsGame of Streams: How to Tame and Get the Most from Your Messaging Platforms
Game of Streams: How to Tame and Get the Most from Your Messaging Platforms
 
Micronaut Launchpad
Micronaut LaunchpadMicronaut Launchpad
Micronaut Launchpad
 

Similar to Introduction to WebMvc.fn

Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with SpringJoshua Long
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Implement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyoImplement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyoToshiaki Maki
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenJoshua Long
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Codemotion
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascriptEldar Djafarov
 
Javaone 2010
Javaone 2010Javaone 2010
Javaone 2010Hien Luu
 
Quick Fetch API Introduction
Quick Fetch API IntroductionQuick Fetch API Introduction
Quick Fetch API IntroductionChris Love
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Michel Schudel
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09Daniel Bryant
 
Consume Spring Data Rest with Angularjs
Consume Spring Data Rest with AngularjsConsume Spring Data Rest with Angularjs
Consume Spring Data Rest with AngularjsCorneil du Plessis
 
Java Configuration Deep Dive with Spring
Java Configuration Deep Dive with SpringJava Configuration Deep Dive with Spring
Java Configuration Deep Dive with SpringJoshua Long
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Javaelliando dias
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New FeaturesJay Lee
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejugrobbiev
 
JAX-RS 2.0 and OData
JAX-RS 2.0 and ODataJAX-RS 2.0 and OData
JAX-RS 2.0 and ODataAnil Allewar
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Michael Plöd
 

Similar to Introduction to WebMvc.fn (20)

Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with Spring
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Implement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyoImplement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot #cf_tokyo
 
JavaCro'15 - GWT integration with Vaadin - Peter Lehto
JavaCro'15 - GWT integration with Vaadin - Peter LehtoJavaCro'15 - GWT integration with Vaadin - Peter Lehto
JavaCro'15 - GWT integration with Vaadin - Peter Lehto
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in Heaven
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
Javaone 2010
Javaone 2010Javaone 2010
Javaone 2010
 
Quick Fetch API Introduction
Quick Fetch API IntroductionQuick Fetch API Introduction
Quick Fetch API Introduction
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
 
Consume Spring Data Rest with Angularjs
Consume Spring Data Rest with AngularjsConsume Spring Data Rest with Angularjs
Consume Spring Data Rest with Angularjs
 
Java Configuration Deep Dive with Spring
Java Configuration Deep Dive with SpringJava Configuration Deep Dive with Spring
Java Configuration Deep Dive with Spring
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
 
JavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
JavaCro'14 - Building interactive web applications with Vaadin – Peter LehtoJavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
JavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New Features
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejug
 
JAX-RS 2.0 and OData
JAX-RS 2.0 and ODataJAX-RS 2.0 and OData
JAX-RS 2.0 and OData
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6
 

More from VMware Tanzu

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItVMware Tanzu
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023VMware Tanzu
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleVMware Tanzu
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023VMware Tanzu
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductVMware Tanzu
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready AppsVMware Tanzu
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And BeyondVMware Tanzu
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfVMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023VMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023VMware Tanzu
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptxVMware Tanzu
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchVMware Tanzu
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishVMware Tanzu
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVMware Tanzu
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - FrenchVMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023VMware Tanzu
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootVMware Tanzu
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerVMware Tanzu
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeVMware Tanzu
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsVMware Tanzu
 

More from VMware Tanzu (20)

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About It
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at Scale
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a Product
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready Apps
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And Beyond
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptx
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - French
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - English
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - English
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - French
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software Engineer
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs Practice
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 

Recently uploaded

Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine HarmonyLeveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmonyelliciumsolutionspun
 
Kawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLAlluxio, Inc.
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadIvo Andreev
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Jaydeep Chhasatia
 
online pdf editor software solutions.pdf
online pdf editor software solutions.pdfonline pdf editor software solutions.pdf
online pdf editor software solutions.pdfMeon Technology
 
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.Sharon Liu
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorShane Coughlan
 
Introduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptxIntroduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptxIntelliSource Technologies
 
AI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyAI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyRaymond Okyere-Forson
 
Why Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfWhy Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfBrain Inventory
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionsNirav Modi
 
Top Software Development Trends in 2024
Top Software Development Trends in  2024Top Software Development Trends in  2024
Top Software Development Trends in 2024Mind IT Systems
 
Webinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.pptWebinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.pptkinjal48
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIIvo Andreev
 
Growing Oxen: channel operators and retries
Growing Oxen: channel operators and retriesGrowing Oxen: channel operators and retries
Growing Oxen: channel operators and retriesSoftwareMill
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilVICTOR MAESTRE RAMIREZ
 
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdfARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdfTobias Schneck
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...OnePlan Solutions
 

Recently uploaded (20)

Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine HarmonyLeveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
 
Salesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptxSalesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptx
 
Kawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in Trivandrum
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and Bad
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
 
online pdf editor software solutions.pdf
online pdf editor software solutions.pdfonline pdf editor software solutions.pdf
online pdf editor software solutions.pdf
 
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS Calculator
 
Introduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptxIntroduction-to-Software-Development-Outsourcing.pptx
Introduction-to-Software-Development-Outsourcing.pptx
 
AI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyAI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human Beauty
 
Why Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfWhy Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdf
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspections
 
Top Software Development Trends in 2024
Top Software Development Trends in  2024Top Software Development Trends in  2024
Top Software Development Trends in 2024
 
Webinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.pptWebinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.ppt
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AI
 
Growing Oxen: channel operators and retries
Growing Oxen: channel operators and retriesGrowing Oxen: channel operators and retries
Growing Oxen: channel operators and retries
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-Council
 
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdfARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
 

Introduction to WebMvc.fn

  • 1. Confidential │ ©2020 VMware, Inc. Introduction to WebMvc.fn Functional Servlet Endpoints Arjen Poutsma (@poutsma) Sr. Staff Engineer at VMware 3rd September 2020
  • 2. Confidential │ ©2020 VMware, Inc. Agenda 2 Handler Functions Router Functions Filter Functions Final Comparison
  • 3. Confidential │ ©2020 VMware, Inc. 3 WebMvc.fn was introduced in Spring 5.2 and is fully compatible with Spring Boot
  • 4. Confidential │ ©2020 VMware, Inc. Handler Functions Map from ServerRequest to ServerResponse 4
  • 5. Confidential │ ©2020 VMware, Inc. 5 Map from ServerRequest to ServerResponse Handler Functions @Controller class PersonController { PersonRepository repository; ResponseEntity<Person> getPerson(@PathVariable String id) { Person person = repository.findById(id); return ResponseEntity.ok() .contentType(APPLICATION_JSON) .body(person); } ResponseEntity<List<Person>> getPeople() { List<Person> people = repository.findAll(); return ResponseEntity.ok() .contentType(APPLICATION_JSON) .body(people); } } Web MVC
  • 6. Confidential │ ©2020 VMware, Inc. 5 Map from ServerRequest to ServerResponse Handler Functions @Controller class PersonHandler { PersonRepository repository; ServerResponse getPerson(ServerRequest request) { String id = request.pathVariable("id"); Person person = repository.findById(id); return ServerResponse.ok() .contentType(APPLICATION_JSON) .body(person); } ServerResponse getPeople(ServerRequest request) { List<Person> people = repository.findAll(); return ServerResponse.ok() .contentType(APPLICATION_JSON) .body(people); } } WebMvc.fn
  • 7. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 6 Handler Function Comparison @Controller class PersonController { PersonRepository repository; ResponseEntity<Person> getPerson(@PathVariable String id) { Person person = repository.findById(id); return ResponseEntity.ok() .contentType(APPLICATION_JSON) .body(person); } ResponseEntity<List<Person>> getPeople() { List<Person> people = repository.findAll(); return ResponseEntity.ok() .contentType(APPLICATION_JSON) .body(people); } } @Controller class PersonHandler { PersonRepository repository; ServerResponse getPerson(ServerRequest request) { String id = request.pathVariable("id"); Person person = repository.findById(id); return ServerResponse.ok() .contentType(APPLICATION_JSON) .body(person); } ServerResponse getPeople(ServerRequest request) { List<Person> people = repository.findAll(); return ServerResponse.ok() .contentType(APPLICATION_JSON) .body(people); } }
  • 8. Confidential │ ©2020 VMware, Inc. 7 Handler Functions map from ServerRequest to ServerResponse • both are immutable • create response with builder
  • 9. Confidential │ ©2020 VMware, Inc. Router Functions Map from ServerRequest to HandlerFunction 8
  • 10. Confidential │ ©2020 VMware, Inc. 9 Map from ServerRequest to HandlerFunction Router Functions @Controller @RequestMapping("/people") class PersonController { PersonRepository repository; @RequestMapping(value = "/{id}", method = GET) ResponseEntity<Person> getPerson(@PathVariable String id) { ... } @RequestMapping(method = GET) ResponseEntity<List<Person>> getPeople() { ... } } Web MVC
  • 11. Confidential │ ©2020 VMware, Inc. 9 Map from ServerRequest to HandlerFunction Router Functions @Controller class PersonHandler { PersonRepository repository; ServerResponse getPerson(ServerRequest request) { ... } ServerResponse getPeople(ServerRequest request) { ... } @Bean static RouterFunction router(PersonHandler handler) { return route() .GET("/people/{id}", handler::getPerson) .GET(“/people", handler::getPeople) .build(); } } WebMvc.fn
  • 12. Confidential │ ©2020 VMware, Inc. 9 Map from ServerRequest to HandlerFunction Router Functions @Controller class PersonHandler { PersonRepository repository; ServerResponse getPerson(ServerRequest request) { ... } ServerResponse getPeople(ServerRequest request) { ... } @Bean static RouterFunction router(PersonHandler handler) { return route() .path(“/people", builder -> builder .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople)); .build(); } } WebMvc.fn
  • 13. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 10 Router Function Comparison @Controller class PersonHandler { PersonRepository repository; ServerResponse getPerson(ServerRequest request) { ... } ServerResponse getPeople(ServerRequest request) { ... } @Bean static RouterFunction router(PersonHandler handler) { return route() .path(“/people", builder -> builder .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople)); .build(); } } @Controller @RequestMapping(“/people") class PersonController { PersonRepository repository; @RequestMapping(value = "/{id}", method = GET) ResponseEntity<Person> getPerson(@PathVariable String id) { ... } @RequestMapping(method = GET) ResponseEntity<List<Person>> getPeople() { ... } }
  • 14. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 10 Router Function Comparison @Controller class PersonHandler { PersonRepository repository; ServerResponse getPerson(ServerRequest request) { ... } ServerResponse getPeople(ServerRequest request) { ... } @Bean static RouterFunction router(PersonHandler handler) { return route() .path(“/people", builder -> builder .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople)); .build(); } } @Controller @RequestMapping(“/people") class PersonController { PersonRepository repository; @RequestMapping(value = "/{id}", method = GET) ResponseEntity<Person> getPerson(@PathVariable String id) { ... } @RequestMapping(method = GET) ResponseEntity<List<Person>> getPeople() { ... } }
  • 15. Confidential │ ©2020 VMware, Inc. 11 Router Functions created using builder • GET, POST, PUT, etc. • resources • nesting • more powerful abstraction underneath: RequestPredicate
  • 16. Confidential │ ©2020 VMware, Inc. Request Predicates Evaluate on a ServerRequest 12
  • 17. Confidential │ ©2020 VMware, Inc. 13 Evaluate on a ServerRequest Request Predicates RequestPredicate get = RequestPredicates.method(HttpMethod.GET); RequestPredicate people = RequestPredicates.path("/people"); RequestPredicate getPeople = get.and(people); // or RequestPredicates.GET("/people") RequestPredicate acceptJson = RequestPredicates.accept(APPLICATION_JSON); RequestPredicate extensionJson = RequestPredicates.pathExtension("json"); RequestPredicate paramTypeJson = RequestPredicates.param("type", "json"); RequestPredicate json = acceptJson.or(extensionJson).or(paramTypeJson);
  • 18. Confidential │ ©2020 VMware, Inc. 14 Evaluate on a ServerRequest Request Predicates @Controller class PersonHandler { PersonRepository repository; ... ServerResponse createPerson(ServerRequest request) { Person person = request.body(Person.class); repository.savePerson(person); return ServerResponse.ok() .build(); } @Bean static RouterFunction router(PersonHandler handler) { return route() .path("/people", b -> b .GET("/{id}", accept(APPLICATION_JSON), handler::getPerson) .GET("/", accept(APPLICATION_JSON), handler::getPeople) .POST("/", contentType(APPLICATION_JSON), handler::createPerson)) .build(); } }
  • 19. Confidential │ ©2020 VMware, Inc. 14 Evaluate on a ServerRequest Request Predicates @Controller class PersonHandler { PersonRepository repository; ... ServerResponse createPerson(ServerRequest request) { Person person = request.body(Person.class); this.repository.savePerson(person); return ServerResponse.ok() .build(); } @Bean static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) { return route() .path(“/people", b -> b .nest(accept(APPLICATION_JSON), b1 -> b1 .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople) ) .POST("/", contentType(APPLICATION_JSON), handler::createPerson)) .build(); } }
  • 20. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 15 Request Predicates Comparison @Controller @RequestMapping(“/people”) class PersonController { PersonRepository repository; @RequestMapping(value = "/{id}", method = GET, produces = APPLICATION_JSON_VALUE) ResponseEntity<Person> getPerson(@PathVariable String id) { ... } @RequestMapping(method = GET, produces = APPLICATION_JSON_VALUE) ResponseEntity<List<Person>> showPeople() { ... } @RequestMapping(method = POST, consumes = APPLICATION_JSON_VALUE) void createPerson(RequestEntity<Person> person) { ... } } @Controller class PersonHandler { PersonRepository repository; ... @Bean static RouterFunction router(PersonHandler handler) { return route() .path(“/people", b -> b .GET("/{id}", accept(APPLICATION_JSON), handler::getP .GET("/", accept(APPLICATION_JSON), handler::getPeopl .POST("/", contentType(APPLICATION_JSON), handler::cr .build(); } }
  • 21. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 15 Request Predicates Comparison @Controller @RequestMapping(“/people”) class PersonController { PersonRepository repository; @RequestMapping(value = "/{id}", method = GET, produces = APPLICATION_JSON_VALUE) ResponseEntity<Person> getPerson(@PathVariable String id) { ... } @RequestMapping(method = GET, produces = APPLICATION_JSON_VALUE) ResponseEntity<List<Person>> showPeople() { ... } @RequestMapping(method = POST, consumes = APPLICATION_JSON_VALUE) void createPerson(RequestEntity<Person> person) { ... } } @Controller class PersonHandler { PersonRepository repository; ... @Bean static RouterFunction router(PersonHandler handler) { return route() .path(“/people", b -> b .GET("/{id}", accept(APPLICATION_JSON), handler::getP .GET("/", accept(APPLICATION_JSON), handler::getPeopl .POST("/", contentType(APPLICATION_JSON), handler::cr .build(); } }
  • 22. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 16 Request Predicates Comparison @Controller class PersonHandler { PersonRepository repository; ... @Bean static RouterFunction<ServerResponse> routerFunction(Person return route() .path("/person", b -> b .nest(accept(APPLICATION_JSON), b1 -> b1 .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople) ) .POST("/", contentType(APPLICATION_JSON), handler::cr .build(); } } ?
  • 23. Confidential │ ©2020 VMware, Inc. Handler Filter Functions Maps ServerRequest and HandlerFunction to ServerResponse 17
  • 24. Confidential │ ©2020 VMware, Inc. 18 Maps ServerRequest and HandlerFunction to ServerResponse Handler Filter Functions @Controller @RequestMapping("/people") class PersonController { PersonRepository repository; ... @ExceptionHandler(NotFoundException.class) ResponseEntity notFound() { return ResponseEntity.notFound().build() } } Web MVC
  • 25. Confidential │ ©2020 VMware, Inc. 18 Maps ServerRequest and HandlerFunction to ServerResponse Handler Filter Functions @Controller class PersonHandler { PersonRepository repository; ... ServerResponse notFound(Throwable throwable, ServerRequest request) { return ServerResponse.notFound().build(); } @Bean static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) { return route() .path(“/people", b -> b .nest(accept(APPLICATION_JSON), b1 -> b1 .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople) ) .POST("/", contentType(APPLICATION_JSON), handler::createPerson)) .onError(NotFoundException.class, handler::notFound) .build(); } } WebMvc.fn
  • 26. Confidential │ ©2020 VMware, Inc. 18 Maps ServerRequest and HandlerFunction to ServerResponse Handler Filter Functions @Controller class PersonHandler { PersonRepository repository; ... ServerResponse notFound(Throwable throwable, ServerRequest request) { return ServerResponse.notFound().build(); } @Bean static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) { return route() .path(“/people", b -> b .nest(accept(APPLICATION_JSON), b1 -> b1 .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople) .onError(NotFoundException.class, handler::notFound) ) .POST("/", contentType(APPLICATION_JSON), handler::createPerson)) .build(); } } WebMvc.fn
  • 27. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 19 Handler Filter Function Comparison @Controller @RequestMapping("/people") class PersonController { PersonRepository repository; ... @ExceptionHandler(NotFoundException.class) ResponseEntity notFound() { return ResponseEntity.notFound().build() } } @Controller class PersonHandler { PersonRepository repository; ... ServerResponse notFound(Throwable throwable, ServerRequest request) { return ServerResponse.notFound().build(); } @Bean static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) { return route() .path("/person", b -> b .nest(accept(APPLICATION_JSON), b1 -> b1 .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople) ) .POST("/", contentType(APPLICATION_JSON), handler::createPerson)) .onError(NotFoundException.class, handler::notFound) .build(); } }
  • 28. Confidential │ ©2020 VMware, Inc. Web MVC WebMvc.fn 19 Handler Filter Function Comparison @Controller @RequestMapping("/people") class PersonController { PersonRepository repository; ... @ExceptionHandler(NotFoundException.class) ResponseEntity notFound() { return ResponseEntity.notFound().build() } } @Controller class PersonHandler { PersonRepository repository; ... ServerResponse notFound(Throwable throwable, ServerRequest request) { return ServerResponse.notFound().build(); } @Bean static RouterFunction<ServerResponse> routerFunction(PersonHandler handler) { return route() .path("/person", b -> b .nest(accept(APPLICATION_JSON), b1 -> b1 .GET("/{id}", handler::getPerson) .GET("/", handler::getPeople) ) .POST("/", contentType(APPLICATION_JSON), handler::createPerson)) .onError(NotFoundException.class, handler::notFound) .build(); } }
  • 29. Confidential │ ©2020 VMware, Inc. Final Comparison 20
  • 30. Confidential │ ©2020 VMware, Inc. • Functions • Code • Rigid handler methods (ServerRequest→ServerResponse) • Flexible routing • Annotations • Meta-data • Flexible handler methods (parameters & return type) • Limited routing Web MVC WebMvc.fn 21 Request Predicates Comparison
  • 31. Confidential │ ©2020 VMware, Inc. Thank You