Unleashing the Dynamic Duo Dr. Rubén Mondéjar Grails & Angular
About Me twitter : @Ruuben4 homepage : http://deim.urv.cat/~ruben.mondejar Working Groovy & Grails AngularJS MicroServices Teaching / Research Software Architecture Web Development Distributed Systems
Contents Introduction Best Solution Conclusions
Contents Introduction Angular2 Profile Conclusions
Single Page Application Inception
Architecture
Architecture
Back-End
Back-End
Front-End
Front-End
SPA Frameworks
How it feels to learn JavaScript (2016) https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f
Angular2 Profile Grails 3.2.1+
Grails 2 + Angular ●Summary : ○Groovy Calamari Issue 70 http://groovycalamari.com/issues/70 ●Example https://github.com/rmondejar/grails-angular-duo
Grails 3.x ●Gradle powered sdk use install 3.2.6 sdk use grails 3.2.6
●Gradle powered ●Angular2 profile Grails 3.2.1+ sdk use grails 3.2.6 grails create-app --inplace -profile angular2
client/ gradle/ gradlew gradlew.bat server/ settings.gradle Grails 3.2.1+ ●Gradle powered ●Angular2 profile ○Folder separation sdk use grails 3.2.6 grails create-app --inplace -profile angular2
REST API /server/grails-app/domain/duo/Example.groovy import grails.rest.Resource @Resource(uri='/examples') class Example { String title int num } /server/grails-app/init/duo/Bootstrap.groovy class BootStrap { def init = { servletContext -> 10.times { new Example(title: "Example #${it+1}", num: it+1).save() } } (...) server/grails create-domain-class duo.Example http://localhost:8080/examples [{"id":1,"num":1,"title":"Example #1"}, {"id":2,"num":2,"title":"Example #2"}, {"id":3,"num":3,"title":"Example #3"}, {"id":4,"num":4,"title":"Example #4"}, {"id":5,"num":5,"title":"Example #5"}, {"id":6,"num":6,"title":"Example #6"}, {"id":7,"num":7,"title":"Example #7"}, {"id":8,"num":8,"title":"Example #8"}, {"id":9,"num":9,"title":"Example #9"}, {"id":10,"num":10,"title":"Example #10"}]
Local Execution ./gradlew server:bootRun http://localhost:8080/ Starting a Gradle Daemon (subsequent builds will be faster) :server:compileJava UP-TO-DATE :server:compileGroovy UP-TO-DATE :server:buildProperties UP-TO-DATE :server:processResources UP-TO-DATE :server:classes UP-TO-DATE :server:findMainClass :server:bootRun Grails application running at http://localhost:8080 in environment: development
Client side ●Minimal NPM ecosystem 1. NVM tool (optional) 2. Node (NPM) 3. Angular CLI
Client side ●Minimal NPM ecosystem ●First time (using nvm tool) curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash nvm install --lts nvm use node npm install -g angular-cli Requirements ● NVM tool ● Node (NPM) ● Angular CLI export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
Client side ● Minimal NPM ecosystem ● First time (using nvm tool) ●Typically (fresh terminal) nvm use node Now using node v6.9.5 (npm v3.10.10)
Angular2 ● TypeScript ● Modules ● Components ● Services ● Classes Angular 2 for Java Developers https://www.slideshare.net/slideshow/embed_code/key/BefUJQP36rJ3PM
Angular CLI Angular2 template app
Angular CLI Angular2 template app Scaffolding ng generate class Example -> /client/app/example.ts export class Example { num: number; title: string = ''; constructor(values: Object = {}) { Object.assign(this, values); } }
Angular CLI Scaffold Usage Component ng g component my-new-component Directive ng g directive my-new-directive Service ng g service my-new-service Class ng g class my-new-class Interface ng g interface my-new-interface Module ng g module my-module
REST Client ng generate service Example -> /client/app/example.service.ts get(id: number): Promise<Example> { return this.http.get('http://localhost:8080/examples/${id}') .toPromise().then( (response) => { let example: Example = new Example(response.json()); return template; }) .catch( (error) => { this.handleResponseError(error) }); }
Local Execution ./gradlew server:bootRun ./gradlew client:bootRun http://localhost:8080/ http://localhost:4200 Starting a Gradle Daemon (subsequent builds will be faster) :server:compileJava UP-TO-DATE :server:compileGroovy UP-TO-DATE :server:buildProperties UP-TO-DATE :server:processResources UP-TO-DATE :server:classes UP-TO-DATE :server:findMainClass :server:bootRun Grails application running at http://localhost:8080 in environment: development Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details :client:nodeSetup SKIPPED :client:npmSetup SKIPPED :client:npmInstall UP-TO-DATE :client:bootRun ** NG Live Development Server is running on http://localhost:4200. ** webpack: Compiled successfully. [default] Checking started in a separate process... [default] Ok, 2.106 sec.
Local Execution ./gradlew server:bootRun ./gradlew bootRun --parallel ./gradlew client:bootRun http://localhost:8080/ http://localhost:4200 http://localhost:4200/
Testing Client application comes with some executable tests ./gradlew test Executes unit tests with Karma and Jasmine Integration tests will execute e2e tests with Protractor ./gradlew integrationTest
Build ●Back-End ./gradlew war /server/build/libs/duo.war ●Front-End ng build /client/src/dist
Deployment
Cross-Origin
CORS By default is enabled server/grails-app/conf/application.yml grails: cors: enabled: true REST service can be accessed from different domains
API Securitization Spring Security REST http://alvarosanchez.github.io/grails-angularjs-springsecurity-workshop/
Repository ●Example https://github.com/rmondejar/grails3-angular2-duo
Conclusions In March 2017
Benefits Reduced Toolkit Integrated Tasks Separated Folders
Benefits Extended Profiles Boilerplate code Scaffolding
Improvements Client Scaffolding TypeScript code Unique build Gradle Task (Back-End) More SPA Frameworks Ex. Angular 4
Unleashing the Dynamic Duo Dr. Rubén Mondéjar Grails & Angular

Grails & Angular: unleashing the dynamic duo