DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Frameworks
  4. Functional Programming in Spring MVC

Functional Programming in Spring MVC

Want to learn more about functional programming in Spring MVC?

Hantsy Bai user avatar by
Hantsy Bai
·
Apr. 16, 19 · Presentation
Like (2)
Save
Tweet
Share
11.06K Views

Join the DZone community and get the full member experience.

Join For Free

Spring 5.0 embraced the ReactiveStreams specification and introduced a new Reactive Stack as an alternative to the traditional Servlet stack. And, it also brought a new functional programming model to developers, but it is only supported in the Reactive Stack.

The good news is that, in the coming 5.2, the functional-like APIs are being ported back to the Servlet stack. For those developers who are stuck on Servlet stack and want to experience the new programming model, it is absolutely startling news.

In this post, let’s take a glance at the new functional feature in Spring MVC.

Create a Spring Boot project using Spring initializr (http://start.spring.io), add Web, JPA, Lombok, and H2 starters as dependencies.

NOTE: Please select the new Spring Boot version 2.2.0.BUILD-SNAPSHOT to get the new Spring 5.2.M1 in its dependencies.

Create a simple JPA Entity Post.

@Data@ToString@Builder@NoArgsConstructor@AllArgsConstructor@Entityclass Post {    
  @Id    @GeneratedValue(strategy = AUTO)    
  private Long id;    
  private String title;    
  private String content;
}


And create a Repository for the Post Entity.

interface PostRepository extends JpaRepository<Post, Long> {}


Define a RouterFuncation bean to handle the routing rules.

@Beanpublic RouterFunction<ServerResponse> routes(PostHandler postController) {    
  return route(GET("/posts"), postController::all)        
    .andRoute(POST("/posts"), postController::create)        
    .andRoute(GET("/posts/{id}"), postController::get)        
    .andRoute(PUT("/posts/{id}"), postController::update)        
    .andRoute(DELETE("/posts/{id}"), postController::delete);
}


The code is almost the same as the ones we have used in Reactive stack, but note here the ServerRequest, ServerResponse, and RouterFunction are imported from the new package:org.springframework.web.servlet.function.

Let’s have a look at the details of PostHandler.

@Componentclass PostHandler {    
  private final PostRepository posts;    
  public PostHandler(PostRepository posts) {        
    this.posts = posts;    }    
  public ServerResponse all(ServerRequest req) {        
    return ServerResponse.ok().body(this.posts.findAll());    }    
  public ServerResponse create(ServerRequest req) 
    throws ServletException, IOException {        
    var saved = this.posts.save(req.body(Post.class));        
    return ServerResponse.created(URI.create("/posts/" + saved.getId())).build();    }    
  public ServerResponse get(ServerRequest req) {        
    return this.posts.findById(Long.valueOf(req.pathVariable("id")))            
      .map(post -> ServerResponse.ok().body(post))            
      .orElse(ServerResponse.notFound().build());    }    
  public ServerResponse update(ServerRequest req) 
    throws ServletException, IOException {        var data = req.body(Post.class);        return this.posts.findById(Long.valueOf(req.pathVariable("id")))            .map(                post -> {                    post.setTitle(data.getTitle());                    post.setContent(data.getContent());                    return post;                }            )            .map(post -> this.posts.save(post))            .map(post -> ServerResponse.noContent().build())            .orElse(ServerResponse.notFound().build());    }    public ServerResponse delete(ServerRequest req) {        return this.posts.findById(Long.valueOf(req.pathVariable("id")))            .map(                post -> {                    this.posts.delete(post);                    return ServerResponse.noContent().build();                }            )            .orElse(ServerResponse.notFound().build());    }}


It is very similar to the codes of Reactive Stack, and but the methods return a ServerResponse instead of Mono<ServerResponse>.

Like the RouterFunctionDSL feature provided in Reactive Stack, the routing rules can also be written in Kotlin DSL.

router {        
  "/posts".nest {            
    GET("", postHandler::all)            
      GET("{id}", postHandler::get)            
      POST("", postHandler::create)            
      PUT("{id}", postHandler::update)            
      DELETE("{id}", postHandler::delete)        
  }    
}


Besides these, MockMvc also gets the support of Kotlin DSL; you can write your tests in a fluent style like the following.

@Test  fun `Get all posts should ok`() {        
  mockMvc                
    .get("/posts") {                    
    accept = APPLICATION_JSON headers {                        
      contentLanguage = Locale.ENGLISH                    
    }                
  }.andExpect {                    
    status { isOk }                    
    content { contentType(APPLICATION_JSON_UTF8) }                    
    jsonPath("$[0].title") { value(containsString("post")) 
                           }                 
  }                
  .andDo {                    
    print()                
  }    
}


Check out the source code from my GitHub and compare it with the code that I had written to demonstrate Reactive Stack.

Spring Framework Functional programming

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Why Every Fintech Company Needs DevOps
  • PostgreSQL: Bulk Loading Data With Node.js and Sequelize
  • Top Five Tools for AI-based Test Automation
  • Visual Network Mapping Your K8s Clusters To Assess Performance

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: