Microservices
Grails or Spring Boot?
Fátima Casaú
@fatimacasau / {PARADIGMA TECNOLÓGICO
About me
Fátima Casaú Pérez / @fatimacasau
Software Engineer for over 7 years ago
Java Architect & Scrum Master in Paradigma
Tecnológico
Specialized in Groovy & Grails environments
Recently, Spring Boot world
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Picture: Cueva La Mora, Embalse García de Sola, Talarrubias (Badajoz)
Overview
Spring Boot, Groovy
GVM Tool
Example 1: Implement simple REST API
●
Spring Boot, Gradle, Groovy, Spring Data JPA
Example 2: Implement simple REST API
●
Grails
Other important Tips
Conclusions
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Spring BootSpring Boot
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Spring Boot
Standalone
Auto-configuration - CoC
No XML
Embedded Container and Database
Bootstrapping
Groovy!!
Run quickly - Spring Boot CLI
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
projects.spring.io/spring-boot
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Groovy
Dynamic language
Optionally typed
@TypeChecked & @CompileStatic
Java Platform
Easy & expressive syntax
Powerful features
closures, DSL, meta-programming, functional programming, scripting,
...
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
www.groovy-lang.org
GVMGVM
Groovy enVironment ManagerGroovy enVironment Manager
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
GVM
Manage parallel versions
Multiple Software Development Kits
– Groovy, Grails, Gradle, Spring Boot, Vert.x, Griffon,...
Unix Sistems
– Linux, Mac OSX, CyWin, Solaris,..
Bash
Curl & Unzip available
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
gvmtool.net
GVM – How to ...
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
$ gvm help
$ curl ­s get.gvmtool.net | bash
$ gvm install groovy
$ gvm install groovy 2.4.0
$ gvm use grails 2.5.0
$ gvm current
$ gvm current gradle
$ gvm list springboot
$ gvm default groovy 2.4.0
$ gvm uninstall grails 2.4.4
Spring Boot App in a single Tweet with Groovy
HelloWorld.groovy
@Controller
class ThisWillActuallyRun {
   @RequestMapping("/")
   @ResponseBody
   String home() {
       "Hello World!"
   }
}
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Spring Boot in a single tweet
Run the Spring Boot Groovy script
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
$ spring run helloWorld.groovy
  .   ____          _            __ _ _
 / / ___'_ __ _ _(_)_ __  __ _    
( ( )___ | '_ | '_| | '_ / _` |    
 /  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |___, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.2.RELEASE)
...
... : Root WebApplicationContext: initialization completed 
in 4024 ms
...
... : Started application in 8.042 seconds (JVM running 
for 15.542)
$ gvm current springboot
Using springboot version 1.2.2.RELEASE
Spring BootSpring Boot
Implement Simple REST APIImplement Simple REST API
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Example 1:Example 1:
How to...
Create project with Gradle
Bootstraping
Create an entity
Create a repository
Create custom controller
Configure properties
Testing
Execute
Deploy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Gradle
Powerful build tool
Support multi-project
Dependency management (based on Apache Ivy)
Support and Integration with Maven & Ivy
repositories
Based on Groovy DSL
Build by convention
Ant tasks
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Gradle
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
$ gvm install gradle
$ mkdir spring­boot­example
$ touch build.gradle
$ mkdir ­p src/main/java/example
$ gradle build
(Edit the file)
build.gradle
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
1  buildscript {   
2  repositories {
3         mavenCentral()
4     }
5     dependencies {
6        classpath("org.springframework.boot:spring­boot­gradle­plugin:1.2.3.RELEASE")
7     }
8   }
9  
10  apply plugin: 'groovy'
11  apply plugin: 'idea'
12  apply plugin: 'spring­boot'
13  
14  jar {
15      baseName = 'helloworld'
16      version = '0.1.0'
17  }
18  
19  repositories {
20      mavenCentral()
21  }
22  
23  dependencies {
24      compile "org.springframework.boot:spring­boot­starter­web"
25      compile "com.h2database:h2"
26      compile "org.codehaus.groovy:groovy­all:2.4.3"
27  }
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Main ClassMain Class
Application main class
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1  import org.springframework.boot.SpringApplication
 2  import org.springframework.boot.autoconfigure.SpringBootApplication
 3  
 4  @SpringBootApplication
 5  public class Application {
 6  
 7   public static void main(String[] args) {
 8   SpringApplication.run(Application.class, args)
 9   }
 10 }
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableWebMvc
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Create an EntityCreate an Entity
build.gradle
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
1  
2  //...
3  
4  dependencies {
5      // include Spring Boot Starter Web
6      compile("org.springframework.boot:spring­boot­starter­data­rest")
7      // include hibernate entity manager
8      compile("org.springframework.boot:spring­boot­starter­data­jpa")
9      compile("com.h2database:h2")
10     compile "org.codehaus.groovy:groovy­all:2.4.3"
11  }
Person.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 
 2 
 3 
 4 
 5 class Person {
 6 
 7 
 8 
 9    long id
 10 
 11 
 12 
 13   String firstName
 14 
 15 
 16   String lastName
 17 
 18 
 19   Integer age
 20 
 21   @Override
 22   String toString(){
 23       "Person: [Name: $firstName, LastName: $lastName, Age: $age]"
 24   }
 25 }
Person.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import javax.persistence.*
 2 import javax.validation.constraints.*
 3 
 4 @Entity
 5 class Person {
 6 
 7    @Id
 8    @GeneratedValue(strategy=GenerationType.AUTO)
 9    long id
 10 
 11   @NotNull
 12   @Size(max = 20)
 13   String firstName
 14 
 15   @Size(max = 50)
 16   String lastName
 17 
 18   @Max(100L)
 19   Integer age
 20 
 21   @Override
 22   String toString(){
 23       "Person: [Name: $firstName, LastName: $lastName, Age: $age]"
 24   }
 25 }
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Create a REST RepositoryCreate a REST Repository
PersonRepository.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 
 2 import org.springframework.data.repository.CrudRepository
 3 
 4 import org.springframework.stereotype.Repository
 5 
 6 @Repository
 7 interface PersonRepository extends CrudRepository<Person,Long> {
 8 
 9   
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 }
PersonRepository.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import org.springframework.data.jpa.repository.Query
 2 import org.springframework.data.repository.CrudRepository
 3 import org.springframework.data.repository.query.Param
 4 import org.springframework.stereotype.Repository
 5 
 6 @Repository
 7 interface PersonRepository extends CrudRepository<Person,Long> {
 8 
 9   List<Person> findByLastName(String name)
 10 
 11  @Query("select p from Person p where p.firstName like %?1")
 12  List<Person> findByFirstNameEndsWith(String firstname)
 13 
 14  @Query("select p from Person p where p.firstName = :firstname or p.lastName =
 15 :lastname")
 16  List<Person> findByLastnameOrFirstname(@Param("lastname") String lastname,
 17                                         @Param("firstname") String firstname)
 18 
 19  @Query(value = "SELECT * FROM PERSON WHERE AGE BETWEEN ?1 AND ?2", 
 20         nativeQuery = true)
 21  List<Person> findByAgeBetween(Integer from, Integer to)
 22 
 23 }
PersonRepository.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import org.springframework.data.jpa.repository.Query
 2 import org.springframework.data.repository.CrudRepository
 3 import org.springframework.data.repository.query.Param
 4 import org.springframework.stereotype.RepositoryRestResource
 5 
 6 @RepositoryRestResource(collectionResourceRel = "people", path = "people")
 7 interface PersonRepository extends CrudRepository<Person,Long> {
 8 
 9   List<Person> findByLastName(String name)
 10 
 11  @Query("select p from Person p where p.firstName like %?1")
 12  List<Person> findByFirstNameEndsWith(String firstname)
 13 
 14  @Query("select p from Person p where p.firstName = :firstname or p.lastName =
 15 :lastname")
 16  List<Person> findByLastnameOrFirstname(@Param("lastname") String lastname,
 17                                         @Param("firstname") String firstname)
 18 
 19  @Query(value = "SELECT * FROM PERSON WHERE AGE BETWEEN ?1 AND ?2", 
 20         nativeQuery = true)
 21  List<Person> findByAgeBetween(Integer from, Integer to)
 22 
 23 }
PersonRepository.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import org.springframework.data.jpa.repository.Query
 2 import org.springframework.data.repository.CrudRepository
 3 import org.springframework.data.repository.query.Param
 4 import org.springframework.stereotype.RepositoryRestResource
 5 
 6 @RepositoryRestResource(exported = false)
 7 interface PersonRepository extends CrudRepository<Person,Long> {
 8 
 9   List<Person> findByLastName(String name)
 10 
 11  @Query("select p from Person p where p.firstName like %?1")
 12  List<Person> findByFirstNameEndsWith(String firstname)
 13 
 14  @Query("select p from Person p where p.firstName = :firstname or p.lastName =
 15 :lastname")
 16  List<Person> findByLastnameOrFirstname(@Param("lastname") String lastname,
 17                                         @Param("firstname") String firstname)
 18 
 19  @Query(value = "SELECT * FROM PERSON WHERE AGE BETWEEN ?1 AND ?2", 
 20         nativeQuery = true)
 21  List<Person> findByAgeBetween(Integer from, Integer to)
 22 
 23 }
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Create a Custom Rest ControllerCreate a Custom Rest Controller
PersonController.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import org.springframework.beans.factory.annotation.Autowired
 2 import org.springframework.web.bind.annotation.PathVariable
 3 import org.springframework.web.bind.annotation.RequestMapping
 4 import org.springframework.web.bind.annotation.RestController
 5 
 6 @RestController
 7 class PersonController {
 8 
 9    @Autowired
 10    PersonRepository personRepository
 11 
 12    @RequestMapping("/person/{id}/address")
 13    Address personAddress(
 14            @PathVariable("id") Long id
 15    ){
 16        personRepository.findOne(id).address
 17    }
 18 
 19 }
Spock FrameworkSpock Framework
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
TestingTesting
Spock Framework
Spock framework & specification
Expressive
Groovy DSL’s
Easy to read tests
Well documented
JUnit
Powerful assertions
Spock & Test Dependencies
1  
2  //...
3  
4  dependencies {
5      // include Spring Boot Starter Web
6      compile("org.springframework.boot:spring­boot­starter­data­rest")
7      // include hibernate entity manager
8      compile("org.springframework.boot:spring­boot­starter­data­jpa")
9      compile("com.h2database:h2")
10     compile "org.codehaus.groovy:groovy­all:2.4.3"
11     compile ("org.codehaus.groovy.modules.http­builder:http­builder:0.7")
12     testCompile("org.springframework.boot:spring­boot­starter­test")
13     testCompile("org.springframework:spring­test")
14     testRuntime("org.spockframework:spock­spring:0.7­groovy­2.0") {
15         exclude group: 'org.spockframework', module: 'spock­core'
16     }
17     testCompile("org.spockframework:spock­core:0.7­groovy­2.0") {
18         exclude group: 'org.codehaus.groovy', module: 'groovy­all'
19     }
20  }
Example Spock Test
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 @WebAppConfiguration
 2 @ContextConfiguration(loader = SpringApplicationContextLoader.class,classes =
 3 [Application.class])
 4 @IntegrationTest("server.port:0")
 5 class PersonRestSpec extends Specification {
 6 
 7     @Value("${local.server.port}")
 8     String contextPath
 9 
 10    @Value("${server.context­path}")
 11    String contextPath
 12 
 13    @Autowired
 14    PersonRepository personRepository
 15 
 16    def "find a person via REST"(){
 17       given: "an existing person"
 18           RESTClient rest = new RESTClient("http://localhost:$port")
 19           def person = personRepository.findAll()[0]
 20       and: "people uri"
 21           def uri = "$contextPath/people/${person.id}"
 22       when:
 23           def result = rest.get(path: uri)
 24       then:
 25           result.status == HttpStatus.OK.value()
 26    }
 27 }
Example Spock Test
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 @Unroll
 2 def "create new person via REST with different params: #params"(){
 3 
 4    setup: "people uri"
 5        RESTClient rest = new RESTClient("http://localhost:$port")
 6        def uri = "$contextPath/people"
 7    expect: "status ok"
 8        result == rest.post(requestContentType: JSON, path: uri, body: params).status
 9    where: "different params"
 10        result                      | params
 11        HttpStatus.CREATED.value()  | [firstName:"fatima",lastName:"casau"]
 12        HttpStatus.OK.value()       | [firstName:"fatima",lastName:"casau",age:29] 
 13        // this fails
 14 
 15 }
Test failed exception
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Pretty tests report
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
ConfigurationConfiguration
Configuration
Properties files
application.properties
YAML
application.yml
By profile
application-{profile}.properties
application-{profile}.yml
Classpath
YAML – Exmaple configuration file
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 spring:
 2   profiles.active: default 
 3 ­­­
 4 spring:
 5   profiles: default
 6 # server config
 7 server.context­path: /springbootexample
 8 # config properties
 9 foo:
 10   firstProperty: firstFooProperty
 11   secondProperty: secondFooProperty
Common application properties:
http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
Access to configuration properties
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 @ConfigurationProperties(prefix = "foo")
 2 class HelloController {
 3 
 4    String firstProperty
 5 
 6    @Value("${foo.secondProperty}")
 7    String secondProperty
 8 
 9    String getFirstProperty() {
 10        return firstProperty
 11   }
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Execute & DeployExecute & Deploy
Execute (packaging Jar or War)
Using Gradle
Using Maven
In place
Create a war file
Gradle: some options in build.gradle
Maven:
$ gradle build && java ­jar build/libs/spring­boot­example­0.1.0.jar
$ mvn package && java ­jar target/spring­boot­example­0.1.0.jar
$ gradle bootRun
$ mvn spring­boot:run
apply plugin: 'war'
war {
    baseName = 'myapp'
    version =  '0.5.0'
}
<packaging>war</packaging>
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Deploy to the cloudDeploy to the cloud
Deploy to the cloud
“Bring your own container”
Jars ready to cloud PaaS
Heroku (install git & Heroku Toolbelt)
Procfile (project root)
Cloud Foundry (install cf command line tool and login in)
Openshift
Google API engine (somo modifications – Servlet 2.5)
$ cf push spring­boot­example ­p build/libs/spring­boot­example­0.1.0.jar
$ cf apps
web: java ­Dserver.port=$PORT ­jar target/demo­0.0.1­SNAPSHOT.jar
$ git push heroku master
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
More examples:More examples:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples
GrailsGrails
Implement Simple REST APIImplement Simple REST API
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Example 2:Example 2:
GrailsGrails
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Grails
Powerful web application Framework
Java Platform (JVM)
Groovy-based
CoC (Convention over Configuration)
ORM/NoSql
Plugins
DSL's
Grails 3 built on Spring Boot
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
How to...
Create project → Bootstraping
Create an Entity
RESTful API
Create REST Controller
Create REST Custom Controller
Testing
Configuration
Execute
Deploy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Create ProjectCreate Project
Create Project - Bootstraping
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
$ grails create­app grails3­api­rest
build.gradle file by default
Main class Application.groovy by default
application.yml configuration by default
Layout & some view by default
i18n files by default
log configuration by default
Url mappings by default
Example HelloWorld
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
$ grails
| Enter a command name to run. Use TAB for completion:
grails> create­controller HelloWorld
| Created grails­app/controllers/grails3/rest/sample/HelloWorldController.groovy
| Created src/test/groovy/grails3/rest/sample/HelloWorldControllerSpec.groovy
grails> 
Grails provides an interactive console
HelloWorldController.groovy class is created
Default controllers directory
Default packaging
package grails3.rest.sample
class HelloWorldController {
    def index() { }
}
{ “Hello World" }
grails> run­app
Example HelloWorld
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
grails> run­app
> Configuring > 0/1 projects > root project > Resolving dependencies ':classpath
1/1 projects > Resolving dependencies ':agent' > Resolving dependencies ':versio
:compileJava UP­TO­DATE
> Building 16% > :compileGroovy > Resolving dependencies ':compile' > Resolving 
:compileGroovy UP­TO­DATE
:processResources
:classes
:findMainClass
> Building 83% > :bootRun > Resolving dependencies ':runtime' > Resolving depend
:bootRun
Grails application running at http://localhost:8080
> Building 83% > :bootRun
gradle tasks
Example HelloWorld
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Create an EntityCreate an Entity
(RESTful API)(RESTful API)
Create domain class
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
grails> create­domain­class Person
| Created grails­app/domain/grails3/rest/sample/Person.groovy
| Created src/test/groovy/grails3/rest/sample/PersonSpec.groov
grails> 
Person.groovy persistence class is created
Default domain directory
package grails3.rest.sample
class Person {
    static constraints = {
    }
}
Person.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import grails.rest.Resource
 2 
 3 
 4 class Person {
 5 
 6    String firstName
 7    String lastName
 8    Integer age
 9 
 10    static constraints = {
 11        lastName maxSize: 20
 12        firstName maxSize: 50
 13        age nullable: true
 14    }
 15 } 16 
Person.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import grails.rest.Resource
 2 
 3 @Resource(uri='/people')
 4 class Person {
 5 
 6    String firstName
 7    String lastName
 8    Integer age
 9 
 10    static constraints = {
 11        lastName maxSize: 20
 12        firstName maxSize: 50
 13        age nullable: true
 14    }
 15 } 16 
Person.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import grails.rest.Resource
 2 
 3 @Resource(uri='/people', formats=['json', 'xml'])
 4 class Person {
 5 
 6    String firstName
 7    String lastName
 8    Integer age
 9 
 10    static constraints = {
 11        lastName maxSize: 20
 12        firstName maxSize: 50
 13        age nullable: true
 14    }
 15 } 16 
Person.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import grails.rest.Resource
 2 
 3 @Resource(uri='/people', readOnly=true)
 4 class Person {
 5 
 6    String firstName
 7    String lastName
 8    Integer age
 9 
 10    static constraints = {
 11        lastName maxSize: 20
 12        firstName maxSize: 50
 13        age nullable: true
 14    }
 15 } 16 
RESTful API only with one annotation
Dynamic finders, where queries, criterias, … without repositories
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Create REST ControllerCreate REST Controller
PersonController.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 import grails.rest.RestfulController
 2 
 3 class PersonController extends RestfulController{
 4 
 5    static responseFormats = ['json', 'xml']
 6 
 7    PersonController(){
 8        super(Person)
 9    }
 10 } 11 
RESTful Url mapping to controller by
convention
in URLMappings.groovy
"/people"(resources: 'person')
HTTP Method URI Grails Action
GET /people index
GET /people/create create
POST /people save
GET /people/${id} show
GET /people/${id}/edit edit
PUT /people/${id} update
DELETE /people/${id} delete
PersonController.groovy
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
 1 @Transactional(readOnly = true)
 2 class PersonController {   
 3     static responseFormats = ['json', 'xml']
 4 
 5     def index(Integer max) {
 6         params.max = Math.min(max ?: 10, 100)
 7         respond Person.list(params), model:[personCount:Person.count()]
 8     }
 9 
 10     def show(Person person) {
 11         if(person) {
 12             render status:404
 13         }
 14         else {
 15             respond person
 16         }
 17     }
 18 
 19 }
HTTP Method URI Grails Action
GET /people index
GET /people/create create
POST /people save
GET /people/${id} show
GET /people/${id}/edit edit
PUT /people/${id} update
DELETE /people/${id} delete
RESTful Url mapping to controller by
convention
in URLMappings.groovy
"/people"(resources: 'person')
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
TestingTesting
Testing
Spock Framework integrated by default
Similar use as Spring Boot
– Well integrated (more easy, more features)
– Test Mixins for Unit test. Support for:
●
Domains and constraints
●
Controllers and filters
●
Tag libraries
●
Url mappings
●
Metaprogramming
– Integration Tests
– Functional Tests (GEB integrated by default)
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
See
Documentation!
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
ConfigurationConfiguration
Configuration
Similar as Spring Boot
Built configuration: build.gradle file
Runtime configuration: grails­app/conf/application.yml by default
Grails 2.0-style: grails­app/conf/application.groovy
Access: grailsApplication.config.getProperty('foo.bar.hello')
Spring @Value annotation
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Configuration per Environments
Easy use of configuration by environments
Commands by environment
– Default environments: grails [environment] [command name]
– Custom environments: grails ­Dgrails.env=[custom­env­name] [command­name]
– Programmatic env. detection, per env. bootstraping, generic per env. execution
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
# Default environments
environments:
    development:
        dataSource:
            dbCreate: create­drop
            url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    test:
        dataSource:
            dbCreate: update
            url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    production:
        dataSource:
            dbCreate: update
            url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        properties:
           jmxEnabled: true
           initialSize: 5
        ...
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Execute & DeployExecute & Deploy
Execute & Deploy
Gradle tasks (run & package)
Grails commands
– run-app environment by default 'development'
– package (executable war of jar)
– war environment by default: 'production' (to deploy in a Servlet Container)
provided "org.springframework.boot:spring­boot­starter­tomcat"
List of supported containers: https://grails.org/wiki/Deployment
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
$ grails [environment] run­app 
$ grails package
$ grails war
Deploy to cloud
Since grails is build on Spring Boot and permits create
standalone applications. The way to deploy on to the cloud is
similar with Spring Boot
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Other Important TipsOther Important Tips
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Other important tips
HAL support
Easy integration with Spring Security
– (Grails Spring Security Core Plugin not Grails3 compatible (use Spring Security
Starter for Spring Boot)
GORM & GSP's in Spring Boot
– Your can use them outside of Grails since Grails 2.4
Grails Scaffolding
Grails autorealoading by default
Grails custom marshalling easily
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
ConclusionsConclusions
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Conclusions
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
With Spring Boot
Groovy language posibility
Build with gradle or maven
Convention Over Configuration
GORM (posibility)
Spock framework (posibility)
Bootstrapping
Configuration (properties, YAML)
Configuration Per Environment
Easy way to execute & deploy
Deploy to the Cloud
HAL support
With Grails 3
Groovy language
Build with gradle by default
Convention Over Configuration ++
GORM by default
Spock framework by default & Text Mixins
Bootstrapping with many config by default
Configuration (properties, YAML, Groovy DSL's)
Config. Per env. (more flixible & more features)
Easy way to execute & deploy
Deploy to the Cloud
HAL support
Plugins Library
Scaffolding
and more...
That's allThat's all
@fatimacasau /{PARADIGMA TECNOLÓGICO
Microservices, Grails or Spring Boot?
Source code: Spring Boot -> https://github.com/fatimacasau/spring-boot-example.git
Source code: Grails 3 -> https://github.com/fatimacasau/grails3-rest-sample.git

Spring IO '15 - Developing microservices, Spring Boot or Grails?

  • 1.
    Microservices Grails or SpringBoot? Fátima Casaú @fatimacasau / {PARADIGMA TECNOLÓGICO
  • 2.
    About me Fátima CasaúPérez / @fatimacasau Software Engineer for over 7 years ago Java Architect & Scrum Master in Paradigma Tecnológico Specialized in Groovy & Grails environments Recently, Spring Boot world @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? Picture: Cueva La Mora, Embalse García de Sola, Talarrubias (Badajoz)
  • 3.
    Overview Spring Boot, Groovy GVMTool Example 1: Implement simple REST API ● Spring Boot, Gradle, Groovy, Spring Data JPA Example 2: Implement simple REST API ● Grails Other important Tips Conclusions @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 4.
    Spring BootSpring Boot @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 5.
    Spring Boot Standalone Auto-configuration -CoC No XML Embedded Container and Database Bootstrapping Groovy!! Run quickly - Spring Boot CLI @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? projects.spring.io/spring-boot
  • 6.
  • 7.
    Groovy Dynamic language Optionally typed @TypeChecked& @CompileStatic Java Platform Easy & expressive syntax Powerful features closures, DSL, meta-programming, functional programming, scripting, ... @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? www.groovy-lang.org
  • 8.
    GVMGVM Groovy enVironment ManagerGroovyenVironment Manager @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 9.
    GVM Manage parallel versions MultipleSoftware Development Kits – Groovy, Grails, Gradle, Spring Boot, Vert.x, Griffon,... Unix Sistems – Linux, Mac OSX, CyWin, Solaris,.. Bash Curl & Unzip available @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? gvmtool.net
  • 10.
    GVM – Howto ... @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? $ gvm help $ curl ­s get.gvmtool.net | bash $ gvm install groovy $ gvm install groovy 2.4.0 $ gvm use grails 2.5.0 $ gvm current $ gvm current gradle $ gvm list springboot $ gvm default groovy 2.4.0 $ gvm uninstall grails 2.4.4
  • 11.
    Spring Boot Appin a single Tweet with Groovy HelloWorld.groovy @Controller class ThisWillActuallyRun {    @RequestMapping("/")    @ResponseBody    String home() {        "Hello World!"    } } @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? Spring Boot in a single tweet
  • 12.
    Run the SpringBoot Groovy script @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? $ spring run helloWorld.groovy   .   ____          _            __ _ _  / / ___'_ __ _ _(_)_ __  __ _     ( ( )___ | '_ | '_| | '_ / _` |      /  ___)| |_)| | | | | || (_| |  ) ) ) )   '  |____| .__|_| |_|_| |___, | / / / /  =========|_|==============|___/=/_/_/_/  :: Spring Boot ::        (v1.2.2.RELEASE) ... ... : Root WebApplicationContext: initialization completed  in 4024 ms ... ... : Started application in 8.042 seconds (JVM running  for 15.542) $ gvm current springboot Using springboot version 1.2.2.RELEASE
  • 13.
    Spring BootSpring Boot ImplementSimple REST APIImplement Simple REST API @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? Example 1:Example 1:
  • 14.
    How to... Create projectwith Gradle Bootstraping Create an entity Create a repository Create custom controller Configure properties Testing Execute Deploy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 15.
  • 16.
    Gradle Powerful build tool Supportmulti-project Dependency management (based on Apache Ivy) Support and Integration with Maven & Ivy repositories Based on Groovy DSL Build by convention Ant tasks @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 17.
    Gradle @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? $ gvm install gradle $ mkdir spring­boot­example $ touch build.gradle $ mkdir ­p src/main/java/example $ gradle build (Edit the file)
  • 18.
    build.gradle @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? 1  buildscript {    2  repositories { 3         mavenCentral() 4     } 5     dependencies { 6        classpath("org.springframework.boot:spring­boot­gradle­plugin:1.2.3.RELEASE") 7     } 8   } 9   10  apply plugin: 'groovy' 11  apply plugin: 'idea' 12  apply plugin: 'spring­boot' 13   14  jar { 15      baseName = 'helloworld' 16      version = '0.1.0' 17  } 18   19  repositories { 20      mavenCentral() 21  } 22   23  dependencies { 24      compile "org.springframework.boot:spring­boot­starter­web" 25      compile "com.h2database:h2" 26      compile "org.codehaus.groovy:groovy­all:2.4.3" 27  }
  • 19.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Main ClassMain Class
  • 20.
    Application main class @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?  1  import org.springframework.boot.SpringApplication  2  import org.springframework.boot.autoconfigure.SpringBootApplication  3    4  @SpringBootApplication  5  public class Application {  6    7   public static void main(String[] args) {  8   SpringApplication.run(Application.class, args)  9   }  10 } @Configuration @EnableAutoConfiguration @ComponentScan @EnableWebMvc
  • 21.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Create an EntityCreate an Entity
  • 22.
    build.gradle @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? 1   2  //... 3   4  dependencies { 5      // include Spring Boot Starter Web 6      compile("org.springframework.boot:spring­boot­starter­data­rest") 7      // include hibernate entity manager 8      compile("org.springframework.boot:spring­boot­starter­data­jpa") 9      compile("com.h2database:h2") 10     compile "org.codehaus.groovy:groovy­all:2.4.3" 11  }
  • 23.
    Person.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1   2   3   4   5 class Person {  6   7   8   9    long id  10   11   12   13   String firstName  14   15   16   String lastName  17   18   19   Integer age  20   21   @Override  22   String toString(){  23       "Person: [Name: $firstName, LastName: $lastName, Age: $age]"  24   }  25 }
  • 24.
    Person.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import javax.persistence.*  2 import javax.validation.constraints.*  3   4 @Entity  5 class Person {  6   7    @Id  8    @GeneratedValue(strategy=GenerationType.AUTO)  9    long id  10   11   @NotNull  12   @Size(max = 20)  13   String firstName  14   15   @Size(max = 50)  16   String lastName  17   18   @Max(100L)  19   Integer age  20   21   @Override  22   String toString(){  23       "Person: [Name: $firstName, LastName: $lastName, Age: $age]"  24   }  25 }
  • 25.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Create a REST RepositoryCreate a REST Repository
  • 26.
    PersonRepository.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1   2 import org.springframework.data.repository.CrudRepository  3   4 import org.springframework.stereotype.Repository  5   6 @Repository  7 interface PersonRepository extends CrudRepository<Person,Long> {  8   9     10   11   12   13   14   15   16   17   18   19   20   21   22   23 }
  • 27.
    PersonRepository.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import org.springframework.data.jpa.repository.Query  2 import org.springframework.data.repository.CrudRepository  3 import org.springframework.data.repository.query.Param  4 import org.springframework.stereotype.Repository  5   6 @Repository  7 interface PersonRepository extends CrudRepository<Person,Long> {  8   9   List<Person> findByLastName(String name)  10   11  @Query("select p from Person p where p.firstName like %?1")  12  List<Person> findByFirstNameEndsWith(String firstname)  13   14  @Query("select p from Person p where p.firstName = :firstname or p.lastName =  15 :lastname")  16  List<Person> findByLastnameOrFirstname(@Param("lastname") String lastname,  17                                         @Param("firstname") String firstname)  18   19  @Query(value = "SELECT * FROM PERSON WHERE AGE BETWEEN ?1 AND ?2",   20         nativeQuery = true)  21  List<Person> findByAgeBetween(Integer from, Integer to)  22   23 }
  • 28.
    PersonRepository.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import org.springframework.data.jpa.repository.Query  2 import org.springframework.data.repository.CrudRepository  3 import org.springframework.data.repository.query.Param  4 import org.springframework.stereotype.RepositoryRestResource  5   6 @RepositoryRestResource(collectionResourceRel = "people", path = "people")  7 interface PersonRepository extends CrudRepository<Person,Long> {  8   9   List<Person> findByLastName(String name)  10   11  @Query("select p from Person p where p.firstName like %?1")  12  List<Person> findByFirstNameEndsWith(String firstname)  13   14  @Query("select p from Person p where p.firstName = :firstname or p.lastName =  15 :lastname")  16  List<Person> findByLastnameOrFirstname(@Param("lastname") String lastname,  17                                         @Param("firstname") String firstname)  18   19  @Query(value = "SELECT * FROM PERSON WHERE AGE BETWEEN ?1 AND ?2",   20         nativeQuery = true)  21  List<Person> findByAgeBetween(Integer from, Integer to)  22   23 }
  • 29.
    PersonRepository.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import org.springframework.data.jpa.repository.Query  2 import org.springframework.data.repository.CrudRepository  3 import org.springframework.data.repository.query.Param  4 import org.springframework.stereotype.RepositoryRestResource  5   6 @RepositoryRestResource(exported = false)  7 interface PersonRepository extends CrudRepository<Person,Long> {  8   9   List<Person> findByLastName(String name)  10   11  @Query("select p from Person p where p.firstName like %?1")  12  List<Person> findByFirstNameEndsWith(String firstname)  13   14  @Query("select p from Person p where p.firstName = :firstname or p.lastName =  15 :lastname")  16  List<Person> findByLastnameOrFirstname(@Param("lastname") String lastname,  17                                         @Param("firstname") String firstname)  18   19  @Query(value = "SELECT * FROM PERSON WHERE AGE BETWEEN ?1 AND ?2",   20         nativeQuery = true)  21  List<Person> findByAgeBetween(Integer from, Integer to)  22   23 }
  • 30.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Create a Custom Rest ControllerCreate a Custom Rest Controller
  • 31.
    PersonController.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import org.springframework.beans.factory.annotation.Autowired  2 import org.springframework.web.bind.annotation.PathVariable  3 import org.springframework.web.bind.annotation.RequestMapping  4 import org.springframework.web.bind.annotation.RestController  5   6 @RestController  7 class PersonController {  8   9    @Autowired  10    PersonRepository personRepository  11   12    @RequestMapping("/person/{id}/address")  13    Address personAddress(  14            @PathVariable("id") Long id  15    ){  16        personRepository.findOne(id).address  17    }  18   19 }
  • 32.
    Spock FrameworkSpock Framework @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? TestingTesting
  • 33.
    Spock Framework Spock framework& specification Expressive Groovy DSL’s Easy to read tests Well documented JUnit Powerful assertions
  • 34.
    Spock & TestDependencies 1   2  //... 3   4  dependencies { 5      // include Spring Boot Starter Web 6      compile("org.springframework.boot:spring­boot­starter­data­rest") 7      // include hibernate entity manager 8      compile("org.springframework.boot:spring­boot­starter­data­jpa") 9      compile("com.h2database:h2") 10     compile "org.codehaus.groovy:groovy­all:2.4.3" 11     compile ("org.codehaus.groovy.modules.http­builder:http­builder:0.7") 12     testCompile("org.springframework.boot:spring­boot­starter­test") 13     testCompile("org.springframework:spring­test") 14     testRuntime("org.spockframework:spock­spring:0.7­groovy­2.0") { 15         exclude group: 'org.spockframework', module: 'spock­core' 16     } 17     testCompile("org.spockframework:spock­core:0.7­groovy­2.0") { 18         exclude group: 'org.codehaus.groovy', module: 'groovy­all' 19     } 20  }
  • 35.
    Example Spock Test @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?  1 @WebAppConfiguration  2 @ContextConfiguration(loader = SpringApplicationContextLoader.class,classes =  3 [Application.class])  4 @IntegrationTest("server.port:0")  5 class PersonRestSpec extends Specification {  6   7     @Value("${local.server.port}")  8     String contextPath  9   10    @Value("${server.context­path}")  11    String contextPath  12   13    @Autowired  14    PersonRepository personRepository  15   16    def "find a person via REST"(){  17       given: "an existing person"  18           RESTClient rest = new RESTClient("http://localhost:$port")  19           def person = personRepository.findAll()[0]  20       and: "people uri"  21           def uri = "$contextPath/people/${person.id}"  22       when:  23           def result = rest.get(path: uri)  24       then:  25           result.status == HttpStatus.OK.value()  26    }  27 }
  • 36.
    Example Spock Test @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?  1 @Unroll  2 def "create new person via REST with different params: #params"(){  3   4    setup: "people uri"  5        RESTClient rest = new RESTClient("http://localhost:$port")  6        def uri = "$contextPath/people"  7    expect: "status ok"  8        result == rest.post(requestContentType: JSON, path: uri, body: params).status  9    where: "different params"  10        result                      | params  11        HttpStatus.CREATED.value()  | [firstName:"fatima",lastName:"casau"]  12        HttpStatus.OK.value()       | [firstName:"fatima",lastName:"casau",age:29]   13        // this fails  14   15 }
  • 37.
    Test failed exception @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 38.
    Pretty tests report @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 39.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? ConfigurationConfiguration
  • 40.
  • 41.
    YAML – Exmapleconfiguration file @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?  1 spring:  2   profiles.active: default   3 ­­­  4 spring:  5   profiles: default  6 # server config  7 server.context­path: /springbootexample  8 # config properties  9 foo:  10   firstProperty: firstFooProperty  11   secondProperty: secondFooProperty Common application properties: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
  • 42.
    Access to configurationproperties @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?  1 @ConfigurationProperties(prefix = "foo")  2 class HelloController {  3   4    String firstProperty  5   6    @Value("${foo.secondProperty}")  7    String secondProperty  8   9    String getFirstProperty() {  10        return firstProperty  11   }
  • 43.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Execute & DeployExecute & Deploy
  • 44.
    Execute (packaging Jaror War) Using Gradle Using Maven In place Create a war file Gradle: some options in build.gradle Maven: $ gradle build && java ­jar build/libs/spring­boot­example­0.1.0.jar $ mvn package && java ­jar target/spring­boot­example­0.1.0.jar $ gradle bootRun $ mvn spring­boot:run apply plugin: 'war' war {     baseName = 'myapp'     version =  '0.5.0' } <packaging>war</packaging>
  • 45.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Deploy to the cloudDeploy to the cloud
  • 46.
    Deploy to thecloud “Bring your own container” Jars ready to cloud PaaS Heroku (install git & Heroku Toolbelt) Procfile (project root) Cloud Foundry (install cf command line tool and login in) Openshift Google API engine (somo modifications – Servlet 2.5) $ cf push spring­boot­example ­p build/libs/spring­boot­example­0.1.0.jar $ cf apps web: java ­Dserver.port=$PORT ­jar target/demo­0.0.1­SNAPSHOT.jar $ git push heroku master
  • 47.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? More examples:More examples: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples
  • 48.
    GrailsGrails Implement Simple RESTAPIImplement Simple REST API @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? Example 2:Example 2:
  • 49.
  • 50.
    Grails Powerful web applicationFramework Java Platform (JVM) Groovy-based CoC (Convention over Configuration) ORM/NoSql Plugins DSL's Grails 3 built on Spring Boot @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 51.
    How to... Create project→ Bootstraping Create an Entity RESTful API Create REST Controller Create REST Custom Controller Testing Configuration Execute Deploy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 52.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Create ProjectCreate Project
  • 53.
    Create Project -Bootstraping @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? $ grails create­app grails3­api­rest build.gradle file by default Main class Application.groovy by default application.yml configuration by default Layout & some view by default i18n files by default log configuration by default Url mappings by default
  • 54.
    Example HelloWorld @fatimacasau /{PARADIGMATECNOLÓGICO Microservices, Grails or Spring Boot? $ grails | Enter a command name to run. Use TAB for completion: grails> create­controller HelloWorld | Created grails­app/controllers/grails3/rest/sample/HelloWorldController.groovy | Created src/test/groovy/grails3/rest/sample/HelloWorldControllerSpec.groovy grails>  Grails provides an interactive console HelloWorldController.groovy class is created Default controllers directory Default packaging package grails3.rest.sample class HelloWorldController {     def index() { } } { “Hello World" } grails> run­app
  • 55.
    Example HelloWorld @fatimacasau /{PARADIGMATECNOLÓGICO Microservices, Grails or Spring Boot? grails> run­app > Configuring > 0/1 projects > root project > Resolving dependencies ':classpath 1/1 projects > Resolving dependencies ':agent' > Resolving dependencies ':versio :compileJava UP­TO­DATE > Building 16% > :compileGroovy > Resolving dependencies ':compile' > Resolving  :compileGroovy UP­TO­DATE :processResources :classes :findMainClass > Building 83% > :bootRun > Resolving dependencies ':runtime' > Resolving depend :bootRun Grails application running at http://localhost:8080 > Building 83% > :bootRun gradle tasks
  • 56.
    Example HelloWorld @fatimacasau /{PARADIGMATECNOLÓGICO Microservices, Grails or Spring Boot?
  • 57.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Create an EntityCreate an Entity (RESTful API)(RESTful API)
  • 58.
    Create domain class @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? grails> create­domain­class Person | Created grails­app/domain/grails3/rest/sample/Person.groovy | Created src/test/groovy/grails3/rest/sample/PersonSpec.groov grails>  Person.groovy persistence class is created Default domain directory package grails3.rest.sample class Person {     static constraints = {     } }
  • 59.
    Person.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import grails.rest.Resource  2   3   4 class Person {  5   6    String firstName  7    String lastName  8    Integer age  9   10    static constraints = {  11        lastName maxSize: 20  12        firstName maxSize: 50  13        age nullable: true  14    }  15 } 16 
  • 60.
    Person.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import grails.rest.Resource  2   3 @Resource(uri='/people')  4 class Person {  5   6    String firstName  7    String lastName  8    Integer age  9   10    static constraints = {  11        lastName maxSize: 20  12        firstName maxSize: 50  13        age nullable: true  14    }  15 } 16 
  • 61.
    Person.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import grails.rest.Resource  2   3 @Resource(uri='/people', formats=['json', 'xml'])  4 class Person {  5   6    String firstName  7    String lastName  8    Integer age  9   10    static constraints = {  11        lastName maxSize: 20  12        firstName maxSize: 50  13        age nullable: true  14    }  15 } 16 
  • 62.
    Person.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import grails.rest.Resource  2   3 @Resource(uri='/people', readOnly=true)  4 class Person {  5   6    String firstName  7    String lastName  8    Integer age  9   10    static constraints = {  11        lastName maxSize: 20  12        firstName maxSize: 50  13        age nullable: true  14    }  15 } 16  RESTful API only with one annotation Dynamic finders, where queries, criterias, … without repositories
  • 63.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Create REST ControllerCreate REST Controller
  • 64.
    PersonController.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 import grails.rest.RestfulController  2   3 class PersonController extends RestfulController{  4   5    static responseFormats = ['json', 'xml']  6   7    PersonController(){  8        super(Person)  9    }  10 } 11  RESTful Url mapping to controller by convention in URLMappings.groovy "/people"(resources: 'person') HTTP Method URI Grails Action GET /people index GET /people/create create POST /people save GET /people/${id} show GET /people/${id}/edit edit PUT /people/${id} update DELETE /people/${id} delete
  • 65.
    PersonController.groovy @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot?  1 @Transactional(readOnly = true)  2 class PersonController {     3     static responseFormats = ['json', 'xml']  4   5     def index(Integer max) {  6         params.max = Math.min(max ?: 10, 100)  7         respond Person.list(params), model:[personCount:Person.count()]  8     }  9   10     def show(Person person) {  11         if(person) {  12             render status:404  13         }  14         else {  15             respond person  16         }  17     }  18   19 } HTTP Method URI Grails Action GET /people index GET /people/create create POST /people save GET /people/${id} show GET /people/${id}/edit edit PUT /people/${id} update DELETE /people/${id} delete RESTful Url mapping to controller by convention in URLMappings.groovy "/people"(resources: 'person')
  • 66.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? TestingTesting
  • 67.
    Testing Spock Framework integratedby default Similar use as Spring Boot – Well integrated (more easy, more features) – Test Mixins for Unit test. Support for: ● Domains and constraints ● Controllers and filters ● Tag libraries ● Url mappings ● Metaprogramming – Integration Tests – Functional Tests (GEB integrated by default) @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? See Documentation!
  • 68.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? ConfigurationConfiguration
  • 69.
    Configuration Similar as SpringBoot Built configuration: build.gradle file Runtime configuration: grails­app/conf/application.yml by default Grails 2.0-style: grails­app/conf/application.groovy Access: grailsApplication.config.getProperty('foo.bar.hello') Spring @Value annotation @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 70.
    Configuration per Environments Easyuse of configuration by environments Commands by environment – Default environments: grails [environment] [command name] – Custom environments: grails ­Dgrails.env=[custom­env­name] [command­name] – Programmatic env. detection, per env. bootstraping, generic per env. execution @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? # Default environments environments:     development:         dataSource:             dbCreate: create­drop             url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE     test:         dataSource:             dbCreate: update             url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE     production:         dataSource:             dbCreate: update             url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE         properties:            jmxEnabled: true            initialSize: 5         ...
  • 71.
    @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? Execute & DeployExecute & Deploy
  • 72.
    Execute & Deploy Gradletasks (run & package) Grails commands – run-app environment by default 'development' – package (executable war of jar) – war environment by default: 'production' (to deploy in a Servlet Container) provided "org.springframework.boot:spring­boot­starter­tomcat" List of supported containers: https://grails.org/wiki/Deployment @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? $ grails [environment] run­app  $ grails package $ grails war
  • 73.
    Deploy to cloud Sincegrails is build on Spring Boot and permits create standalone applications. The way to deploy on to the cloud is similar with Spring Boot @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 74.
    Other Important TipsOtherImportant Tips @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 75.
    Other important tips HALsupport Easy integration with Spring Security – (Grails Spring Security Core Plugin not Grails3 compatible (use Spring Security Starter for Spring Boot) GORM & GSP's in Spring Boot – Your can use them outside of Grails since Grails 2.4 Grails Scaffolding Grails autorealoading by default Grails custom marshalling easily @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot?
  • 76.
  • 77.
    Conclusions @fatimacasau /{PARADIGMA TECNOLÓGICO Microservices,Grails or Spring Boot? With Spring Boot Groovy language posibility Build with gradle or maven Convention Over Configuration GORM (posibility) Spock framework (posibility) Bootstrapping Configuration (properties, YAML) Configuration Per Environment Easy way to execute & deploy Deploy to the Cloud HAL support With Grails 3 Groovy language Build with gradle by default Convention Over Configuration ++ GORM by default Spock framework by default & Text Mixins Bootstrapping with many config by default Configuration (properties, YAML, Groovy DSL's) Config. Per env. (more flixible & more features) Easy way to execute & deploy Deploy to the Cloud HAL support Plugins Library Scaffolding and more...
  • 78.
    That's allThat's all @fatimacasau/{PARADIGMA TECNOLÓGICO Microservices, Grails or Spring Boot? Source code: Spring Boot -> https://github.com/fatimacasau/spring-boot-example.git Source code: Grails 3 -> https://github.com/fatimacasau/grails3-rest-sample.git