His Last Framework

Its been a while since I visited my pyschiatrist and now, Chiropractor Dr. Pear – Perspective Readjustment Specialist. Last time, he helped me cope up an aggressive experience with pair programming. The front-desk handed me a big chunk of forms to fill up my software history.

Years of experiencing web frameworks: About 18.
First framework of pain: JSP Model 2, perhaps Applet, can’t remember.
Latest framework of pain: AngularJS
History of major pain points: EJB, WebSphere, WebLogic, Spring, Fusion Middleware, Wicket, ASP.Net Web/MVC, SharePoint, Grails, SpringBoot, Backbone, Ember, AngularJS and innumerable minor ones.
What type of pain is this? (Select one: Sharp, Shooting, Numb): All of them
Approximate location of pain: Initially Back-end. Then moved to Front-end.
Exact location of pain: Depends on Mood.
Frequency of occurrence of major pain: About every 18 months.

I physically submitted the forms and started checking my tweet feed. New tweets from dzone on Top 20 Javascript frameworks; AngularJS Jobs; Best 35 CSS Frameworks; Top 15 build tools for Javascript; AngularJS vs.., no wonder I needed a therapy.

The nurse called me in and after the initial handshake of pulses and vital stats, she said 200. I was idly looking at the magazines – PlayWeb, Maximum Frameworks… Dr. Pear entered after a knock.

Dr. Pear (browsing thru my history rather than looking at me): Oh, Hello! Its been a while from your last visit.
Me: Yes, Doctor.
Dr. Pear: And what brings you here?
Me: Well, Ive been spinning my head with the next web application framework and I haven’t been able to decide quite…
Dr. Pear: Well, the short answer is “As a consultant you should learn all of them !”, ha ha ha… (after a pause) Yeah, yeah I know. Its the viral season of frameworks. The Javascriptarix flu shot we gave last month was really a placebo. So what kind of framework you are really looking for?
Me: (a bit hesitantly) Not sure, Ive been taking the Javascript MVC Kool-aid for the last couple of years, but it looks like the pain isn’t gone…
Dr. Pear looked at me a bit condescendingly and said “MVC eh? in Javascript? Didn’t you get high enough on it in the Java/.Net world?”.
Me: Well, the Java web frameworks are kinda relegated to providing data services these days…

I had not finished. It must have triggered a raw nerve in him and he went on to a mini lecture of sorts.

“You see, web frameworks come in two general flavors – MVC and Component. Java failingly flirted with the Applet component model initially, and then took a stab at MVC via JSP Model 2, while ASP.Net took the component route after its success with Visual Basic. Interestingly, Java increasingly adapted the component framework model, but Microsoft abandoned ASP.Net Web in favor of ASP.Net MVC. Java/JVM probably tasted all kinds of frameworks in many levels – MVC (Struts, Stripes, Spring, Grails, Play) and Component oriented (Seam, Tapestry, JSF & Co, Wicket, GWT). The fundamental problem with MVC is – it sprays your logic and model everywhere. Many developers struggle to organize it between “what-they-are” vs “what-they-do”. As the complexity increases, the code gets re-organized by features, each of which in turn have the m-v-and-c. Add on top of that, the domain models and view-models are usually different, the whole thing about models start looking like a beauty pageant.”

He paused a second, probably aiming for me to get the pun.

“Component frameworks couple model and view tightly, because a view makes no sense without a model. But the biggest problem for them came from somewhere else: Javascript. Many pure java web frameworks are relatively stable, because of a stable and backward-compatible Servlet API. But component frameworks relied too much on encapsulating Javascript and HTML and in JS world, Friday’s release is outdated by next day Matinee show. Ajax, jQuery and related libraries innovated way too fast and library encapsulation really made no sense. When the JS libraries went unsupported, it dragged the Java frameworks along. With NodeJs, NPM-modules and unit-testing frameworks offering a vastly superior build ecosystem, life became miserable for frontend developers, bogged down by verbosity and slowness of JVM build tools.”

Me: Well, that’s exactly why I am here for. What is the JS framework you would really recommend?
Dr. Pear: Of course Backbone. I love backbones, especially if they aren’t straight. Get it? Ha ha !

He realized I didn’t look at him very admiringly. He continued.

Dr. Pear: Ok. Well, I hate to say it depends, because you didn’t pay me to hear that. So let me tell you something else. With JS frameworks like Backbone, Knockout and Ember becoming first class citizens, server-side slowly mellowed down to doing CRUDGE-work (Create, Read, Update, Delete, Gather and throw Exceptions), now gloriously termed as Microservices Architecture. With AngularJS offering a complete MVC stack, it doesn’t make sense to write Views in server-side anymore.”

Me: So should I still stick with AngularJS MVW ? Besides its barrage of new vocabulary redefinitions like service, factory, provider, scope, directive, the next version 2.0 promises to be completely different and backward incompatible…
Dr. Pear: Yeah, I heard that. It appears that you really need to work on your persuasion skills on convincing your team about writing in new framework every year.
Me: (I looked at him awkwardly, wondering what to say)
Dr. Pear: (Ignoring my awkward pause) Well, the web has to evolve. Why do you think Javascript is going bonkers with frameworks – they have to compete with rapidly advancing browser features, handheld and wearable devices. Who knows, Javascript could be running inside your brain tomorrow. Ok, so you are now tired of MVC in Javascript world also. What about Facebook ReactJS?
Me: ReactJS. Yes I’ve heard of it. Isn’t that a component oriented JS framework?
Dr. Pear: It sure is. You write HTML directly within Javascript or CoffeeScript or Typescript in an XML like syntax and compile them to Javascript.
Me: Im not sure I like the sound of that. Thats not even the best practice.
Dr. Pear: Well, its time to Refactor the Best Practices too. IMO, ReactJS may indeed work out well, because unlike the Java component frameworks, its closer to Javascript, it uses Virtual DOM providing fantastic rendering speeds and helps write isomorphic apps. If you get used to JSX, you will love it.
Me: What about Services?
Dr. Pear: Use one of the many flavors of Flux, Reflux, Fluxxor, Alt – the Action oriented one-way-data-flow-store.
Me: Hmm, that eerily reminds me of Struts. So, there is no really a best framework?
Dr. Pear: There is one – come up with your own. You will surely get a few fans.
Me: What if I get bored and jump ship to another framework? What about the developers who depend on my framework?

“Send them to me!” Dr. Pear said calmly, washing his hands for no reason. “If anyone thinks JS frameworks have more than 18 months of fame, they need a Perspective Readjustment”.

As I was leaving, he gave a parting shot, “Just remember one thing, if it makes you feel any better: no matter which framework, you are solving only a single problem: Delivering html to a browser. And by the way, if you haven’t selected your styling framework, I am open on Saturday afternoon”.

“Er.. Thanks, I will think about it”, I said as I flipped my phone to follow @ReactJS feed on my twitter.

As I was walking out I could see him frantically typing on the screen “Successfully readjusted for component framework. Will likely come here in the next 12 months looking for Web Component and Polymer adjustment.”

Note: Title is a tribute to AC Doyle’s His Last Bow.

Defining React Routers via API

One of the issues I faced while using React for my project is which Router to use? React obviously being a new framework on the block, there are plenty of plugins/components that are being actively developed and not many are (yet) stable. Some plugins are just enough different for you to want a new feature, but it wont support other features required. You can see how bullet-point engineering does not help much. You gotta try out a few and see what works best.

For the Router, react-router is the most popular, featured and well-documented, but it (v0.12.0) did not have one feature I was looking for: Ability to define routers closest to the handler itself.

All the routes go into a single file, usually your app.js, like this:

var routes = (
  <Route name="app" path="/" handler={App}>
    <Route name="login" path="/login" handler={Login}/>
    <Route name="logout" path="/logout" handler={Logout}/>
    <Route name="page1" path="/page1" handler={Page1}/>
    <Route name="page2" path="/page2" handler={Page2}/>
    <DefaultRoute handler={Login}/>
  </Route>
);

Router.run(routes, function(Handler) {
  React.render(<Handler/>, document.body);
});

If the application grows, this is less than ideal and can bloat the app.js. And it somewhat breaks modularity too (even though the app.js will eventually know everything, it forces you to wire the routes statically). The react-mini-router defines the routes as part of component as a mixin and I think thats pretty convenient.

With react-router v0.12.2+ the routes can be configured via api. This is not documented yet officially, afaik.

approute.js

module.exports = Router.createRoute({ name: "app", path: "/", handler: App});

auth.js

var AppRoute = require('./approute.js');
Router.createRoute({ name: "login", path: "/login", parentRoute: AppRoute, handler: Login});
Router.createRoute({ name: "logout", path: "/logout", parentRoute: AppRoute, handler: Logout});

page1.js

var AppRoute = require('./approute.js');
Router.createRoute({ name: "page1", path: "/page1", parentRoute: AppRoute, handler: Page1});


app.js

var AppRoute = require('./approute.js');
Router.createDefaultRoute({parentRoute: AppRoute, handler: Login});

Router.run([ AppRoute ], function (Handler) {
  React.render(<Handler/>, document.body);
});

Notice how the variable routes is replaced with [ AppRoute ]. This is important!.

In auth.js, if defining multiple routes, If you dont want to use parentRoute property, you can also do this:

AppRoute.addRoutes([ LoginRoute, LogoutRoute ]);

AngularJS – Startup time environment configuration

Starting to learn a web framework, doesn’t matter which platform – Spring, AngularJS, Grails, Rails etc. is easy. But once you go past the elementary-school level status, a question always looms – how to accomplish tasks the framework-way versus the non-framework way?

A seemingly simple stuff like configuring environment properties at runtime (startup), took me through internals of AngularJS. For server-side folks, the technique is pretty standard: use any of .properties, .xml, .yaml and then apply a built-in framework feature. For eg. in Spring, you can using the @ConfigureProperties, for Grails, use the Config.groovy and the framework will automatically place it in grailsApplication, similar to what Rails does. But how do you do it for a purely client side application (ie ‘static’ site, that relies only on rest calls from some other server)?

AngularJS allows a Module.constant() method, where you can just specify a Javascript object and DI-it where-ever you want. Neat. But often the config values are environment specific. One of the very nice solutions is to use grunt-replace and simply provide the environment specific json at build time and grunt replaces the config values for that build. One may argue that this is the correct way to do, because it provides consistency and tracebality in CI.

But in some cases the values may not be known ahead before build and is known only at application startup. So the question is what is the AngularJS way of loading the configuration file at startup? Would have been nice to have AngularJs look for a config.json properties file at root and automatically load and inject it into a variable like $env.

Obviously, AngularJS offers so much stuff – constant, value, service, factory, provider. I thought I need to stick the $http somewhere and load the config.json file and set it to AngularJS constant or value. Then inject the constant to any controller or service.

1. Inject $http into Module.constant()

Will not work, constant accepts only an object and not services. At this point of time, it is useful to get familiar with config and run phases of AngularJS. This stackoverflow question explains succinctly.

2. Inject $http into Module.config()

Will not work. You cannot inject a AngularJS service into config. You can inject only a provider into config.

var envconfig = angular.module('envconfig', []);

envconfig.config(['$http', function($http) {
var envConfig = {
restUrl: 'http://localhost:8080/rest/api/'
};

$http.get('/config.json').onSuccess(function(data) {
envConfig = data;
});
}]);

So, how about injecting a provider into config, and let the provider use the $http ?

3. Inject $http into the provider

Will not work. You cannot inject a service ($http) directly into a provider, like this:

envconfig.provider('EnvConfig', function($http) {
});

Though you can use a service within the provider, like this:

envconfig.provider('EnvConfig', function() {
var envConfig = {
restUrl: 'http://localhost:8080/rest/api/'
};

var loadConfig = ['$http', function($http) {
$http.get('/config.json').success(function(data) {
envConfig = data;
});
return envConfig;
}];

//This $get, is kinda confusing - it does not return the provider, but it returns the "service".
//In our case, the "service" is the environment configuration object
//The $get is called automatically when AngularJS encounters a DI.
this.$get = loadConfig;
});

If you want to further configure the Provider, you can do this. Notice that the “Provider” suffix must be appended EnvConfig.

envconfig.config(['EnvConfigProvider', function(EnvConfigProvider) {
//Do something with EnvConfigProvider
}]);

While this almost works, there is a problem: $http is an asynchronous call, so its not guaranteed that the data will be returned with the values read from the config.json. Very likely the local envConfig will be returned always.

To get around you have to make $http a sync call, which is not possible. So we go deeper into the underlying framework of AngularJS – jQuery.

4. Load config.json synchronously

In the provider, you can do the following:

envconfig.provider("EnvConfig", function() {
this.$get = function() {
var q = jQuery.ajax({
type: 'GET', url: '/config.json', cache: false, async: false, contentType: 'application/json', dataType: 'json'
});
if (q.status === 200) {
angular.extend(envConfig, angular.fromJson(q.responseText));
}
return envConfig;
}];
});

Notice, that the q.responseText is a string and is converted to Json object using angular.fromJson(). Also by using angular.extend, you can merge the local envConfig with the target one – this allows you to keep some default values that you dont want to immediately expose.

5. How about profiles?

If you have multiple profiles in the config.json, you can simply use the following technique:

this.$get = ['$location', function($location) {
var profile = $location.search().profile || 'default';
var q = jQuery.ajax({
type: 'GET', url: '/config.json', cache: false, async: false, contentType: 'application/json', dataType: 'json'
});
if (q.status === 200) {
angular.extend(envConfig, angular.fromJson(q.responseText)[profile]);
}

return envConfig;
}];

And your config.json is like:

{
  "development": { "restUrl" : "http://devserver/rest/api" },
  "qa": { "restUrl" : "http://qaserver/rest/api" }
}

And then call your url as http://localhost:9000/index.html?profile=development

While adding profile query string may not be recommended for production, if you are testing your UI against several backend instances, this might just help.

Thoughts on SpringBoot

In its new avatar, Spring enters the opinionated frameworks marketspace, and finally takes the Sinatra/Scalatra/Ratpack/Dropwizard/Spark route, where embedded containers (ie no external server containers) will start dictating the future. Whats an opinionated framework anyway? Aint all frameworks opinionated? To me every piece of code is just as opinionated as the developer who wrote it. Here are my observations about SpringBoot, after having worked with it for about 6 weeks.

1. Build support for gradle (+)
SpringBoot apps can be built using both maven and gradle. But I believe Gradle will eventually dominate the world of buildscripts. So the sooner your team moves to gradle, better will be your quality of this life and perhaps, next life too. Are you listening, .Net?

2. Starter poms (+)
Remember your 500 line pom.xml, where the tag <dependency> occurs 25000 times? Say good bye and start using starter-poms. Combined with gradle, a typical build file is now about 30 lines.

3. Configurations (+/-)
Spring is among the last standing action heros of xml-based application configuration in jvm world. Super hit when introduced, but soon became a liability. Thankfully, many developers challenged the xml tag soup and created innovative web frameworks (Wicket, Play etc.). Those who work with the Spring-based framework Grails, may have not touched an xml for a good period of time. If Spring MVC developers are still stuck with Spring without adapting Grails, I fail to understand why (well except for business impositions).

Ironically, SpringBoot seems to have many opinions when it comes to configuration – it supports 3 flavors of bean configurations: xml, annotation and groovy dsl. Having worked with Grails and other non-xml based applications for the last few years, picking up SpringBoot was bit of a chore. Grails autowires beans by name, and when custom beans are required, there is this wonderful bean builder. For me, java annotations are no better than xml configuration. Xml configuration proliferates verbosity but annotations defeat the purpose of wiring objects separate from code. While it brings type-safety, it also lets you mix code, configuration and logic and I think its a total mess. Annotations are like antibiotics – good in small doses (@ToString, @RestController, @AutoClone etc.), too many side-effects with overdose – building whole applications using annotations is @NotMyStyleOfTea.

A typical SpringBoot application has many many annotations – @EnableAutoConfiguration, @Configuration, @ComponentScan, @Conditional etc. Sometimes you end up with more annotations than the code itself and its not intuitive which is doing what when how. SpringBoot is certainly simpler for developers from xml background, but to me as a Grails developer, annotations have been a bit intimidating and sprawling. I don’t see CoC (Convention-over-Configuration), instead I see CoC (Configuration-over-Code).

Thankfully, SpringBoot has great (although not 1:1 xml equivalent) support for groovy beans dsl (via the GroovyBeanDefinitionReader). Groovy dsl is elegant, concise, intuitve and very readable. For some loss of type-safety (which could have been compensated by good tooling support), it comes with a great punch – wiring beans, environmental configurations, programmatic startup logic (as opposed to declarative) etc. I feel Spring can standardize groovy bean as the only configuration mechanism and shed all the fat of xmls and annotations. It would make the framework pretty lean and competitive in the already crowding lean frameworks market. May be thats what grails-boot is?

4. Properties (+/-)
Just like configurations, there are a few ways of defining and injecting properties. Coming from Grails background, the many ways of injecting properties was a bit confusing. SpringBoot supports both .properties and .yaml files. AutoConfiguration uses many default values for properties, but there is no comprehensive documentation on these properties on whats default. Again there are many annotations related to properties @ConfigurationProperties, @PropertySource, @Value, @EnableConfigurationProperties etc. Grails has this amazing single-point grailsApplication bean based on ConfigObject (a glorified Map) and allows nested and runtime evaluate-able configurations – helpful in dynamic scenarios. Again I wish Spring had defacto support for this (injecting properties from a config.groovy).

5. Rest Support (+)
SpringBoot makes it very easy to create rest controllers via @RestController. Instead of creating full-blown web applications, Spring’s eco can be used to create well-rounded rest services backed by Batch/Data/Integration/Security and use js frameworks like Angular/Knockout/Backbone etc. for front end. If using rest over json, Groovy 2.3 is promising to come up with fast json marshaller. While I like the cleanliness of Thymeleaf, the modern js frameworks have a clear advantage over server-side html generators.

6. Logging (+/-)
Yet again, too many logging frameworks in the bag: log4j, log4j2, slf4j, slf4j2, commons.log, java.util.log, logback. I spent some time resolving dependency conflicts, until I finally gave up and switched to logback. Spring team strongly recommends logback – Just Go with it – there is probably a good reason.

7. Data Access (+)
No question about Spring’s versatility here. Name any db and you have SpringBoot autoconfiguration support. Plus the Grails team has done a great job of spinning-off Gorm to standalone component. TexMex, I would say.

8. Testing (+/-)
Many examples still show use of JUnit, but here is a good start on how to use the incredible Spock framework in SpringBoot. Spock is like mom’s recipe – once you taste it, others aint the best.

9. Documentation (+)
It has improved a lot with newer minor releases. It takes time to sift through some old examples in the community, but lets just blame Google for not knowing what you exactly want, though it seems to know all about what food you want to eat when you are near a restaurant.

10. Finally
I think Grails3 (grails-boot?) is going down the trending route of embedded container deployments. I think that’s the only thing against Grails in the current trend. SpringBoot has got there first but I still feel it lacks the simplicity of Grails or the leanness of Play. It has certainly been simplified, but not simple.

If your existing eco system depends a lot on Spring based frameworks, it is worthwhile to adapt SpringBoot. Honestly, Im hoping Grails3 isn’t far off!

The GroovySpringBootBatchGormGroovyDslBeanFactory

See spring-boot-batch-sample at github for the updated source code.

I was recently working on setting up a not-so-trivial Spring Batch application and wanted to use SpringBoot, because of its embeded-web container capabilities. I could have used Grails and Spring Batch plugin, but wanted to give an opportunity for our Ops/DevOps team a peek at running and maintaining apps via plain “java -jar”. I hadn’t used Spring since 2009 (switching between SharePoint and Grails). Xml is no more a necessity for Spring and it has good support for java annotation configuration. But I am not very comfortable with annotation oriented programming. Xml provided the separation of wiring dependencies from code, but its verbose. Annotations are less verbose, but allows to mix configurations, logic and code, which I feel can spiral out of control pretty soon. I still feel wiring dependencies independently of “code” is a very desirable feature for large applications. Both xml and annotations seem to be at opposite ends of the spectrum.

Fortunately there is a middle ground. SpringBoot provides support for Groovy beans dsl, via the GroovyBeanDefinitionReader. Groovy bean dsls solve the problems of xml and annotations: DI wiring + concise readable syntax + some logic (eg environment-based). But this comes at a price of loosing type-safety. I am surprised that groovy dsl has not yet gone mainstream with Spring apps. If Spring comes with a Groovy DSLD schema (may be there is one already?), it could be a killer feature. For example, Spring Integration is already offering a dsl based “workflow”, which is pretty elegant to read, write and maintain.

I was also new to SpringBatch so it took a while to get them all wired up. So here is a starting point, if you want to use Groovy lang + SpringBoot + SpringBatch + Groovy DSL + Gorm. I haven’t figured out dsl equivalents of @EnableScheduling and @Scheduled yet.

Part 1: appcontext.groovy

//Note that config is not defined as a bean, but directly evaluated and then injected into other beans
//the 'grailsApplication' equivalent
ConfigObject configObject = new ConfigSlurper().parse(Config)

//Note the syntax beans {} not beans = {} like in Grails resources.groovy
beans {

	xmlns([ctx: 'http://www.springframework.org/schema/context', batch: 'http://www.springframework.org/schema/batch'])
	ctx.'component-scan'('base-package': 'org.mypackage')
	ctx.'annotation-config'()

	myController(MyController) {
		config = configObject 
	}

	myService(MyService) {
		config = configObject 
  }

  //MyItemReader implements ItemReader
	myItemReader(MyItemReader) { bean ->
		bean.initMethod = 'init' //required if initializing some data from external dao
		bean.scope = 'step' //for job restartability
	}

	myItemProcessor(MyItemProcessor) {
		myService = ref('myService')
	}

	myItemWriter(FlatFileItemWriter) {
		lineAggregator = new DelimitedLineAggregator(delimiter: ',', fieldExtractor: new BeanWrapperFieldExtractor(names: ["id", "title"]))
		resource = '/apps/springboot/myproject/output'
	}

  //create a job
	batch.job(id: 'job1') {
		batch.step(id: 'step1') {
			batch.tasklet {
				batch.chunk(
					reader: 'myItemReader',
					writer: 'myItemWriter',
					processor: 'myItemProcessor',
					'commit-interval': 10
				)
			}
		}
	}

  //the following beans are minimum mandate because there is no equivalent of xml's <batch:job-repository /> in groovy dsl
  //http://stackoverflow.com/questions/23436477/groovy-bean-syntax-for-spring-batch-job-repository
  //thanks to https://github.com/johnrengelman/grails-spring-batch/blob/master/SpringBatchGrailsPlugin.groovy for the bean definitions
	jobRepository(MapJobRepositoryFactoryBean) {
		transactionManager = ref('transactionManager')
	}

	jobRegistry(MapJobRegistry) { }

	jobLauncher(SimpleJobLauncher) {
		jobRepository = ref('jobRepository')
		taskExecutor = { SyncTaskExecutor executor -> }
	}

	jobExplorer(JobExplorerFactoryBean) {
    //dataSource is auto-configured
		dataSource = ref('dataSource')
	}

	jobOperator(SimpleJobOperator) {
		jobLauncher = ref('jobLauncher')
		jobRepository = ref('jobRepository')
		jobRegistry = ref('jobRegistry')
		jobExplorer = ref('jobExplorer')
	}

}

Part 2: Application and Scheduler

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableScheduling
class MyJobApplication {

	private static final Logger logger = LoggerFactory.getLogger(MyJobApplication.class.getName())

	@Autowired
	JobLauncher jobLauncher

	@Autowired
	Job myJob

//  You can also create configObject bean like this and refer back in beans.groovy using ref('config')
//	@Bean(name="config")
//	ConfigObject configObject() {
//		return new ConfigSlurper().parse(Config)
//	}

	
  @Scheduled(fixedDelayString = '${myJobFixedDelay}', initialDelayString = '${myJobInitialDelay}')
	public void startMyJob() {
		logger.info "startMyJob()"
    //Add time if your job runs repeatedly on different parameters - this will make it an unique entry in the batch-job tables
		JobParameters jobParameters = new JobParametersBuilder().addLong("time",System.currentTimeMillis()).toJobParameters()
		jobLauncher.run(myJob, jobParameters)
	}

	public static void main(String[] args) {
		logger.info "Starting MyJobApplication..."
		Object[] sources = [MyJobApplication.class, new ClassPathResource("appcontext.groovy")]
		SpringApplication.run(sources, args);
	}
}

Part 3: Datasource

Datasource bean is autoconfigured via @EnableAutoConfiguration and if you define the application.properties (or application.yaml). Just add the right driver in your build.gradle. If you dont specify any, hsql db is used.

Part 4: build.gradle

buildscript {
	ext {
		springBootVersion = '1.0.2.RELEASE'
		spockVersion = '0.7-groovy-2.0'
	}
	repositories {
		mavenLocal()
		mavenCentral()
		maven { url "http://repo.spring.io/libs-snapshot" }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
	baseName = 'myapp'
	version = '0.1'
}

repositories {
	mavenCentral()
	mavenLocal()
	maven { url "http://repo.spring.io/libs-snapshot" }
}

dependencies {
	compile("org.springframework.boot:spring-boot-starter-web")
	//if you want to use Jetty, instead of Tomcat, replace the above line with the next two lines
	//compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") { exclude module: "spring-boot-starter-tomcat" }
	//compile("org.springframework.boot:spring-boot-starter-jetty:0.5.0.M2")
	compile("org.springframework.boot:spring-boot-starter-actuator")
	compile("org.springframework.boot:spring-boot-starter-batch")
	compile("org.springframework.boot:spring-boot-starter-logging")
	compile("org.springframework.boot:spring-boot-starter-jdbc")

  compile("org.codehaus.groovy:groovy-all:2.2.2")
	
  compile("org.springframework:spring-orm:4.0.3.RELEASE")
  //For those Grails guys, just throw in the new and shiny standalone gorm dependency
	compile("org.grails:gorm-hibernate4-spring-boot:1.0.0.RC3") {
    //currently brings in spring-orm:3.2.8, exclude it and explicitly include new one above
		exclude module: 'spring-orm'
	}

	testCompile "org.springframework.boot:spring-boot-starter-test"
	testCompile "org.spockframework:spock-core:${spockVersion}"
	testCompile "org.spockframework:spock-spring:${spockVersion}"
}

task wrapper(type: Wrapper) {
	gradleVersion = '1.11'
}

A few more features for the future:

1. Defining multiple datasources in groovy dsl
2. Using spring-loaded for hot-swapping runtime (as of now I can’t get this to work with Intellij Idea)
3. Using Spring-batch-admin to control jobs via UI

Spring Boot with Groovy config

While working on converting a Grails application to a SpringBoot based application, I was trying to understand how the auto configurations and custom configurations work under the hood. Just like CoC of Groovy/Grails, there seems to be a lot of hide-and-seek going on under the Spring boot hood. Admittedly its been a while for me with good ol’ raw Spring, so the many different ways of skinning the configuration felt a bit overwhelming. I counted several concepts around configurations – application.properties, application.yaml, PropertySource, PropertyPlaceHolder, @Value, @EnableConfiguration, @EnableConfigurationProperties, @EnableAutoConfiguration, @Configuration, @ConfigurationProperties, pre-defined property name prefixes, creating classes specifically for holding configuration values – so much information just for accessing key-value pairs? Compare to Grails – one Config.groovy (or multiple externalized) and a simple grailsApplication injection takes care of making configuration available anywhere. When I read Spring Boot support for Groovy, I somehow assumed that support for a groovy config is automatically enabled.

My Grails application already had a groovy config, and I was not in a mood to convert them to .properties or .yaml. Groovy configs are DSLs in essence – it provides many advantages over the traditional properties file: key=value (like .properties), a structured format like .yaml – sans the indent-erasure-phobia, type-enriched config values like list/map etc, functions via closures and more.

So, here is a very simple way to expose the groovy config to your Spring Boot apps:

Create a Config.groovy in the same folder as the ConfigProperties class.

/** Config.groovy **/

//simple key-value
spring.boot.guide = 'https://github.com/spring-guides?page=1'
//formatted structure
google {
searchurl = 'http://www.google.com'
apiKey = '1234'
}

/** ConfigProperties.groovy **/

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class ConfigProperties {

@Bean(name="configObject")
ConfigObject configObject() {
return new ConfigSlurper().parse(Config)
}

}
/** HelloController.groovy **/

import ConfigProperties
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class HelloController {
@Autowired
ConfigObject configObject

@RequestMapping("/")
String home() {
return "Hello World! " + configObject.spring.boot.guide
}

}

/** Application.groovy **/

@EnableAutoConfiguration
@ComponentScan
class Application {
static void main(String[] args) {
Object[] sources = [Application.class, ConfigProperties.class]
SpringApplication.run(sources, args)
}
}

Note: @Bean returns must be typed. Habitually, I wrote def configObject() { return new ConfigSlurper().parse(Config) } and the @Autowired did not wire it up.

Grails Application with AngularJS: Calling a Rest Service – Part 5

Remember the core principle of MVC? Clean separation of model, control and view? Many MVC frameworks, but there hardly is a single framework that provides a puritanical separation between layers. In some, the view is polluted with server-side syntax (jsp, gsp, asp), its equivalents (taglib) or specialized templates (velocity, freemarker); in some others, the server-side code is interspersed with view layer abstractions (css class, href links) or its equivalent html wrappers. One way to measure good separation is how close the view layer is to html semantics itself.

In this part, let us see how we can combine the power of Angular and simplicity of Grails (mainly because of conventions) to make a better separation of model and view.

Note: For the brevity of this post, the tests are not explained, but is included in the github. Specifically, take a look at how angular-mocks provides a cool $httpBackend object that acts as a http service for unit tests and how to invoke them in the controllerSpecs.js.

Goal: Display a star catalog

Techniques Demonstrated

  1. Retrieve Star catalog from server via ajax rest call (demonstrates Rest, Ajax and Angular’s $http)
  2. Show/Hide star catalog (demonstrates Angular’s implicit scope values)
  3. Display the json model in table format (demonstrates Angular’s ng-repeat directive)
  4. Simple Grails 2.3.x Rest services (demonstrates Grails 2.3.x Rest capabilities)

Ingredients

  • Star domain class, decorated with @Resource annotation to make it Rest-enabled
  • New Angular controller to initiate an http request
  • http.get() ajax call to retrieve data from Star domain class and bind to Angular scope
  • Html table to display scope data

Step: Create Star domain class

cmd> cd c:\projects\angrails
cmd> grails create-domain-class angular.Star

Update the code as:

package angrails
import grails.rest.Resource
@Resource(uri='/starCatalog', formats=['json', 'xml'])
class Star {
String name
 String constellation
 //Bayer Designation
 String bd
 //Distance from Earth in light years
 Integer distance
static constraints = {
 }
}

There are many ways to create restful services in Grails 2.3.x, this is one of the easiest ways – create a domain object and add a @Resource annotation. Works for prototypes, demos and really simple applications. For an advanced method, you may want to use RestController and other methods.

Step: Add some seed data to Bootstrap.groovy

def init = { servletContext -&gt;
 new Star(name: 'Aldebaran', constellation: 'Taurus', bd: 'Alpha Tauri', distance: 65).save(flush:true)
 new Star(name: 'Betelgeuse', constellation: 'Orion', bd: 'Alpha Orionis', distance: 640).save(flush:true)
 new Star(name: 'Regulus', constellation: 'Leo', bd: 'Alpha Leonis', distance: 79).save(flush:true)
 new Star(name: 'Spica', constellation: 'Virgo', bd: 'Alpha Virginis', distance: 260).save(flush:true)
 }
cmd> grails run-app
Goto http://localhost:8080/angrails/starCatalog

You should see json representation of the records from Star domain class. Grails auto-generates Rest url end point /starCatalog.

Step: Create Angular Controller and http.get ajax call

Create another controller (next to the MainCtrl) in angrailsApp.js:

angrailsApp.controller('StarCatalogCtrl',
	function ($scope, $http) {

		$scope.getStarCatalog = function () {
			$http.get('/angrails/starCatalog').
				success(function (data) {
					console.log(&quot;success: &quot; + data);
					$scope.starCatalog = data;
				}).error(function (data) {
					console.log(&quot;error: &quot; + data);
					$scope.starCatalog = data;
				});
		};

		$scope.getStarCatalog();
	}
);

1. As a convention, I keep Angular controller suffix as “*Ctrl”, while Grails controllers as “*Controller”.
2. Observe that one more parameter is being added to the function – $http. When Angular runs the javascript, it injects a http service object into $http automatically.
3. The $http.get() does the ajax call to the auto-generated Grails Rest endpoint
4. The result data is set to a new variable in scope – “starCatalog”. We will use this variable to display the table data

Step: Display data in table

You can run crazy with your imagination on how to display the data, but a simple step is shown here:

&lt;div ng-controller=&quot;StarCatalogCtrl&quot;&gt;
	&lt;span&gt;&lt;a href=&quot;#&quot; ng-click=&quot;starCatalogShow = !starCatalogShow&quot;&gt;Star Catalog&lt;/a&gt;&lt;/span&gt;
	&lt;div ng-show=&quot;starCatalogShow&quot;&gt;
		&lt;div&gt;
			&lt;table class=&quot;table&quot;&gt;
				&lt;tr&gt;
					&lt;th&gt;Common name&lt;/th&gt;
					&lt;th&gt;Constellation&lt;/th&gt;
					&lt;th&gt;Bayer Designation&lt;/th&gt;
					&lt;th&gt;Distance from Earth (light years)&lt;/th&gt;
				&lt;/tr&gt;
				&lt;tr ng-repeat=&quot;star in starCatalog&quot;&gt;
					&lt;td&gt;{{star.name}}&lt;/td&gt;
					&lt;td&gt;{{star.constellation}}&lt;/td&gt;
					&lt;td&gt;{{star.bd}}&lt;/td&gt;
					&lt;td&gt;{{star.distance}}&lt;/td&gt;
				&lt;/tr&gt;
			&lt;/table&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;

A few points of interest here:

  • AngularJS Directives (ng-show, ng-click, ng-controller, ng-repeat) do appear to be a cleaner way of extending html behaviour.
  • Directive ng-controller=StarCatalogCtrl specifies which controller provides the scope of the data
  • How an implicit scope variable “starCatalog” hides/shows the table (within the span tag, using the ng-show directive)
  • The ng-repeat Angular directive which is the “forEach (item in itemList)” equivalent to iterate through the starCatalog
  • With this approach, the binding between client and server is a clean http call. This gives you the ability to call any rest service, as long as you can process what you get.

And before we go nuts about AngularJS, observe the syntax of the <a> tag. This type of construct was popular pre-jquery times (<a href=”#”, onclick=”javascript:openLink()”>Click me</a>). With jQuery, there was a big drive towards separation of presentation of data and manipulation of data – using $(id).onClick() syntax. But AngularJS has put the old construct right back into vogue now, but with a twist.

Does this bother you? The pendulum of imperative-declarative programming will swing on forever. Meanwhile, take a look at these articles about Remix and Innovation Recycle bin.

Follow

Get every new post delivered to your Inbox.

Join 216 other followers