SlideShare uma empresa Scribd logo
1 de 31
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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
 

Último

The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 

Último (20)

The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 

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