Introduction to PlayFramework 2.7 ① Overview

Introduction

From now on, we plan to deal with microservices created around the Play Framework (hereafter, Play). Play has a fair number of breaking changes every time the version goes up to 0.1. So, with a view to upgrading some services implemented in the previous version to the latest version, I will (re) introduce to the latest version of Play Framework 2.7 at the moment. I rarely use version 2.6, so I'll keep up with the knowledge of version 2.6.

For those who want to launch play2.7.

Play makes it easy to launch a project based on sbt (seed template command below).

Latest Play Templates for Java:

sbt new playframework/play-java-seed.g8

Latest Play Templates for Scala:

sbt new playframework/play-scala-seed.g8

However, it takes a long time to start up for the first time because the dependent libraries are collected from each repository. When trying out Play, it's a good idea to hit one of the above commands, then sbt run and then collect the necessary information.

In my case, it took about 6 minutes for Play to start in developer mode, and about 30 seconds for the browser to access port 9000, finish the first compilation, and get a response. It will take longer depending on the line condition.

What's new in version 2.7 of Play?

Read "Play 2.7.0 is here!" in the Play Framework Blog. There, eight new features of Play 2.7 are listed. Below, my impression:

gRPC support

A play-grpc based on akka-grpc was provided. From the perspective of developing microservices, I'm happy (although it's currently treated as Incubating). With grpc supported as standard, it will be easier to work with other services using standard schema languages such as Protocol Buffers. If you haven't used Protocol Buffers etc., get an image of the schema language below.

The days when we could only write a single web app that connects to a single RDB are over. The data may be stored in various storage technologies, the backend may be split rather than a single service, and the clients may have web, iOS, and Android versions, each in a different language. It is implemented in, and the API must also be exposed to external developers. Therefore, it is necessary to serialize and deserialize the data everywhere, and to make sure that there is no contradiction in the interpretation at both ends of the communication. However, it is painful to talk to humans in natural language for the purpose of matching, so we want to talk with machine-processable code. Therefore, I want to properly define what kind of data will come in a declarative DSL. So it's a schema language. (Exhibition [Why the schema language is important](https://qiita.com/yugui/items/160737021d25d761b353#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E % E8% A8% 80% E8% AA% 9E% E3% 81% AF% E3% 81% AA% E3% 81% 9C% E9% 87% 8D% E8% A6% 81% E3% 81% AA% E3 % 81% AE% E3% 81% 8B)))

To get an idea of the code, let's take a look at the Hello World grpc example in Play2.7 grpc.

Schema definition of Hello World grpc by Protocol Buffers:

//(Excerpt)
package helloworld;

service GreeterService {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

Implementation example of Greeter Service by Play2.7.

GreeterServiceImpl.scala


/*
 * Copyright (C) 2018-2019 Lightbend Inc. <https://www.lightbend.com>
 */
package example.myapp.helloworld.grpc.helloworld

import akka.stream.Materializer
import javax.inject.Inject
import javax.inject.Singleton

import scala.concurrent.Future

/** User implementation, with support for dependency injection etc */
@Singleton
class GreeterServiceImpl @Inject()(implicit mat: Materializer) extends AbstractGreeterServiceRouter(mat) {
  //Receive Hello Request and Future[HelloReply]SayHello method that returns
  override def sayHello(in: HelloRequest): Future[HelloReply] =
    Future.successful(HelloReply(s"Hello, ${in.name}!")) 
}
// #service-impl

If you've never used akka, there are some terms you can't see, but let's just look at the sayHello method. Since the response of the method is Future [Hello Reply], it can be seen that the services are exchanged asynchronously. This example is currently scala-based, but you can write it in Java as well. The above sayHello method seems to be able to be written like this in Java.

@Override
  public CompletionStage<HelloReply> sayHello(HelloRequest in) {
    String message = String.format("Hello, %s!", in.getName());
    HelloReply reply = HelloReply.newBuilder().setMessage(message).build();
    return CompletableFuture.completedFuture(reply);
  }

Sample code and documentation for grpc is being developed below. https://developer.lightbend.com/docs/play-grpc https://github.com/playframework/play-grpc

It would be great if play2.7's grpc could be the trigger for major JVM-based frameworks (Spring-based) to be connected to each other via grpc. In other words, when the service grows, it may be easier to replace the parts that are heavily affected by garbage collection with C ++ or Go.

Akka-friendly shutdown (Coordinated Shutdown)

It seems that Akka Coordinated Shutdown introduced from Play 2.6 has been incorporated into the Play life cycle in 2.7. This is actually Play 2.7, and you will appreciate it when you create a service that scales up and down at any time.

New cache implementation with Caffeine (Play Cache API)

Play Cache APIs are now based on Java 8-based Caffeine. Caffeine seems to be starting to be used in Spring Boot and so on. This PAI may reduce the number of cases where you have to launch redis etc. externally and cache it.

Support for Enhanced Content Security Policy

I can't comment because I haven't studied "Content Security Policy (https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)", but I would like to take this opportunity to get started.

Reference Study of Contents Security Policy (CSP)

Improved Forms API in Java & made "request data" directly accessible

This seems to be nice in Java. Easily submit forms, simplify code when returning to Http requests (so that you can write without Http.Context), etc.

On the other hand, in play, the previous writing style often doesn't work every time you upgrade, so be careful about changing the writing style. The latter half of the release highlights are listed. https://www.playframework.com/documentation/2.7.x/Highlights27

Renewal of HTTP Error Handlers used in REST API

You'll appreciate it when writing a REST API in Play 2.7. Personally, I would like Play to actively support graphql, which takes advantage of asynchronous base.

Future Primer: Explore the possibilities of grpc + Play.

With the goal of Golden Week, I would like to write an example of a microservice that uses grpc as a glue (connector) in Play2.7.

Recommended Posts

Introduction to PlayFramework 2.7 ① Overview
Introduction to Ruby 2
Introduction to SWING
Introduction to web3j
Introduction to Micronaut 1 ~ Introduction ~
[Java] Introduction to Java
Introduction to migration
Introduction to java
Introduction to Doma
Introduction to EHRbase 1-Overview and Environmental Improvement
Introduction to JAR files
Introduction to Ratpack (8)-Session
Introduction to RSpec 1. Test, RSpec
Introduction to bit operation
Introduction to Ratpack (9) --Thymeleaf
Introduction to Android Layout
Introduction to design patterns (introduction)
Introduction to Practical Programming
Introduction to javadoc command
Introduction to jar command
Introduction to Ratpack (2)-Architecture
Introduction to lambda expression
Introduction to java command
Introduction to RSpec 2. RSpec setup
Introduction to Keycloak development
Introduction to javac command
Introduction to Design Patterns (Builder)
Introduction to RSpec 6. System specifications
Introduction to Android application development
Introduction to RSpec 3. Model specs
Introduction to Ratpack (5) --Json & Registry
Introduction to Metabase ~ Environment Construction ~
Introduction to Ratpack (7) --Guice & Spring
Introduction to Design Patterns (Composite)
Introduction to Micronaut 2 ~ Unit test ~
Introduction to JUnit (study memo)
Introduction to Spring Boot ① ~ DI ~
Introduction to design patterns (Flyweight)
[Java] Introduction to lambda expressions
Introduction to Spring Boot ② ~ AOP ~
Introduction to Apache Beam (2) ~ ParDo ~
[Ruby] Introduction to Ruby Error statement
Introduction to EHRbase 2-REST API
Introduction to design patterns Prototype
GitHub Actions Introduction to self-made actions
[Java] Introduction to Stream API
Introduction to Design Patterns (Iterator)
Introduction to Spring Boot Part 1
Introduction to Ratpack (1) --What is Ratpack?
XVim2 introduction memo to Xcode12.3
Introduction to RSpec-Everyday Rails Summary-
Introduction to Design Patterns (Strategy)
[Introduction to rock-paper-scissors games] Java
[Introduction to Java] About lambda expressions
Introduction to algorithms in java-cumulative sum
Introduction to Functional Programming (Java, Javascript)
Introduction to Ruby processing system self-made
Introduction to algorithms with java-Shakutori method
Introduction to Design Patterns (Factory Method)
Introduction to Linux Container / Docker (Part 2)
Introduction to Design Patterns (Abstract Factory)