Documenting your API with Spring REST Docs

We’ve been using apiDoc.js in a project for a while. While the resulting documentation looks neat, it has several drawbacks in our Java project.

  • It depends on the full blown NPM stack, doesn’t fit well in a Maven build stack. It can be done via the grunt-maven-plugin and a gruntfile.js, but this is very hard to explain to Java only developer
  • Although the comment syntax looks like JavaDoc comments, it isn’t. And that’s a problem for Java 8 JavaDoc compiler: It fails on most of the “special” terms, so we ended up having several resources files next to our controllers, which contain the documentation. That actually defeats the purpose of apiDoc.js.
  • In the end: We are all lazy developers or at least forgetful, so if an API changes, more often then not, we forget to update the documentation

Enter Spring REST Docs. Franz has been tweeting a lot about it lately and after going 1.0, i definitely wanted to check it out.

The head behind Spring REST Docs is Andy Wilkinson and he has done an outstanding job, helping to document existing APIs or prototypes. The documentation alone should answer nearly every question you might have (it would have answered mine if i just had read it better).

I wish i could write a lengthy blog post how hard it was, to an API documentation to my biking Spring Boot demo project, but i can’t.

I basically followed the instruction to add the corresponding maven plugins in the right order as seen in my pom.xml, added an AsciiDoc template for the documentation and then started using my already existing Spring MVC Tests documentation my api:

The result is already online here: Guide and API of biking.michael-simons.eu, the code above creates this part.

I love the beauty of this concept: Leverage existing tests based on Spring MockMvc to generate a tested API documentation: If you add or remove fields, parameters etc. to or from your API, the test will break. Also, documentation and API are in the right place. The toolchain depends on AsciiDoc, but this can easily run with JRuby, so i need no external tooling for generating my application and provide a Maven (or Gradle) based solution for my developers.

One might say Spring REST Docs cannot be used on a whiteboard project or a project designed using WSDL or other tools, but i disagree: Sketching an API using Spring Boot doesn’t take much time and i can always put classes generated from WSDL into a Boot project, use them as parameters or return values and be good.

So if you’re wondering which tool to use to document your api, you should definitively check out Spring REST Docs.

| Comments (1) »

05-Nov-15


Building cloud native apps with Spring Boot in Aachens EuregJUG

This post has been featured on This Week in Spring – October 13, 2015.


euregjug-small

Stéphane Nicoll, working at Pivotal, using Spring since early as 2007 and creating Spring Boot with others since 2014 came over from Liege for the third talk at Aachens EuregJUG this year.

Stéphane had only two slides with him, the rest was live coding / demoing current and upcoming features of Spring Boot. I did take pictures, but neither Stéphane nor Stefan would be happy if upload them i guess, so the picture of the nice banner Stéphane prepared must be enough:


IMG_7621

The idea of the talk was using http://start.spring.io to get a Spring project up and running as fast as possible. The starter is actually the only generation of stuff there is: It generates a Maven or Gradle project configured to use Spring Boot Parent and all starters you selected. Everything after involves no generation.

The starter generator is actually itself a restful Spring Boot application and accessible via CURL, Web and REST endpoints. The REST endpoints are actually used by IntelliJ IDE or STS IDE for nice GUIs generating projects as quick as possible.

What i didn’t know: They’ve also enabled the actuator endpoints, for example the metrics. Nice to see, how the site is being used.

Stéphane showed us how Spring Boot takes opinionated decisions about configuring stuff and how it stays out our your way if you want something else by using security as an example. One cannot stress this enough: Nothing is generated, it’s just configured and for me, thats one of the greatest thing about Spring Boot for since i’m using it as early as version 0.5.

Another important point was the fact that Spring Boot incorporates the Spring IO Platform, a curated list of dependencies that work well with each other. My experiences is that this works really great. Also, you can update or downgrade single libraries if you must by setting just a property in your build file. I wouldn’t recommend it for the Servlet API, but for example changing database drivers etc.

A nice wow effect are the new devtools in upcoming Spring Boot 1.3. They provide a simple but powerful class swapping mechanism and an implementation of the LiveReload protocol. Cannot wait to try them out (as it happens, I’ve upgrade a new application of mine to 1.3.M5 to test the new jOOQ integration). The DevTools will go out of the way if you’re using a JRebel license or Spring Loaded, which is great.

At the end of the nice tour de force, Stéphane pushed the app to Pivotals Cloud Foundry without any changes to the build or code.

If you never used Spring, the talk had a lot of things to show. If you’re long time Spring user, you would be impressed how easy it has become since 5 years ago to deploy a Spring application. And for me, a long time Spring user and early Spring Boot adopter, it was nice seeing a concise presentation of what is possible.

One thought i had during the talk: Spring Boot has a curated list of dependencies, an embedded servlet container (Tomcat, Jetty or Undertow), one of the best dependency injection frameworks their is (Spring Core), for me the best way to interact with JPA (Spring Data JPA) and an actually working MVC framework (Spring MVC): It would be more than justified to call this a Spring Application Server instead of Spring Boot, but I was assured, that’s not gonna happen anytime soon 😉

As with the last time, i didn’t count the visitors, but Stefans picture give you an impression:

And here are some links and tools discussed in the Q&A:

How to support the EuregJUG

If you like those talks in your area: Speak about it, blog about it. Invite colleagues. Maybe leaf an Euro or two in the tip jar, so that we can provide you with a nice experience (drinks etc.).

Come to the monthly meet up in Bar Elementa in Aachen, meet fellow developers.

Don’t be afraid: Even if we blog in English and announce the talks in English, most of us speak German. But we strive to be open for all people in the Euregio and also want foreign speakers to have a clue what’s going on here.

Here are some more information about the EuregJUG Maas-Rhine. The date of our next talk will be announced soon, Bert Jan Schrijver from the NLJUG will speak about “Swimming upstream in the container revolution: Containerless Continuous Delivery”

| Comments (2) »

09-Oct-15


Super simple Java bean tester

This is not about bean testing is effective, right or whatever. Just assume you want your Java beans tested, for example to achieve full code coverage.

There are some solutions out there and I used to use the BeanLikeTester but the library and i have different opinions about the hashCode/equals contract so i decided to run my own in a new project.

This one conveniently tests all setters and getters:

import java.util.Locale;
import java.util.function.BiConsumer;
import org.joor.Reflect;
// If you have jOOQ on the path instead of jOOR
// import org.jooq.tools.reflect.Reflect; 
import org.junit.Assert;
 
public class BeanTester implements BiConsumer<String, Object> {
 
    private final Reflect r;
 
    public BeanTester(Class<?> clazz) {
	this.r = Reflect.on(clazz).create();
    }
 
    @Override
    public void accept(String p, Object v) {
	final String property = p.substring(0, 1).toUpperCase(Locale.ENGLISH) + p.substring(1);
	final String verbSet = "set";
	final String verbGet = v instanceof Boolean ? "is" : "get";
	try {
	    Assert.assertEquals(v, r.call(verbSet + property, v).call(verbGet + property).get());
	} catch(Exception e) {
	    e.printStackTrace();
	    Assert.fail(e.getMessage());
	}
    }
}

You’ll need jOOR to make this work. jOOR is a small but highly functional reflection API.

This is how i use it at the moment:

import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
 
public class BeanTesterDemo {
    static class Demo {
	private String attr1;
 
	private boolean attr2;
 
	private LocalDate attr3;
 
	public String getAttr1() {
	    return attr1;
	}
 
	public void setAttr1(String attr1) {
	    this.attr1 = attr1;
	}
 
	public boolean isAttr2() {
	    return attr2;
	}
 
	public void setAttr2(boolean attr2) {
	    this.attr2 = attr2;
	}
 
	public LocalDate getAttr3() {
	    return attr3;
	}
 
	public void setAttr3(LocalDate attr3) {
	    this.attr3 = attr3;
	}	
    }
 
    @Test
    public void beanShouldWorkAsExpected() {
	final Map<String, Object> values = new HashMap<>();
	values.put("attr1", "foobar");
	values.put("attr2", true);
	values.put("attr3", LocalDate.now());
 
	values.forEach(new BeanTester(Demo.class));
    }
}

| Comments (0) »

01-Oct-15


Thoughts about architecture

Most people slice their cakes like this:


14962767_53ec6ef41e_o

Image by Elaine Ashton

and in most cases not horizontally but still many developers, like i did in the past, slice their packages that way.

Really, just slapping classes into packages named “Model”, “View” and “Controller” doesn’t implement that pattern. @jensschauder has written much more eloquent than i about this here (Jens does also a pretty good talk about that topic and has some really nice drawings in it as well, if you should have the opportunity, check it out) and @olivergierke has taken it further here. Take your time, read both posts. Its worth it. Rethinking my own organization of code the last years helped me writing better code. Looking at a recent project that isn’t divided into libraries yet, i could easily rip those modules apart and deploy them separately.

So, why am i writing this, when so much has already been written by smarter people than i?

The last weeks i’ve been working on a new frontend for an old but really not outdated project that handles a lot of time series, prices and tenders, all in a multi tenant fashion. The database model is really complex but not complicated and is there to stay. The current codebase does many things right in the database (stored PL/SQL procedures) and that won’t change much.

In the course of the last 5 to 8 years I’ve learned so much about Hibernate and got to love the stuff that the Spring Data team is doing on Spring Data JPA and i can say that i really come far, using HQL or now JPQL and also the criteria query api (together with the static meta model) that nobody else seem to like. For example, using semi-joins to determine if stuff is active or not:

public static Specification<Projekt> isAktiv() {
	return (root, query, b) -> {	    
	    final Subquery<String> outerSubquery = query.subquery(String.class);
	    final Root<Projektversion> outerSubqueryRoot = outerSubquery.from(Projektversion.class);
	    final Join<Projektversion, LieferangebotEntity> joinLieferangebot = outerSubqueryRoot.join(lieferangebot);
 
	    final Subquery<String> innerSubquery = query.subquery(String.class);
	    final Root<Projektversion> innerSubqueryRoot = innerSubquery.from(Projektversion.class);
 
	    return b.exists(
		outerSubquery
		    .select(b.literal(""))
		    .where(b.and(
			    b.equal(outerSubqueryRoot.get(projekt), root),
			    b.isNotNull(joinLieferangebot.get(vertragsabschlussdatum))),
			    b.not(b.exists(
				    innerSubquery
					.select(b.literal(""))
					.where(b.and(
						b.equal(innerSubqueryRoot.get(projekt), outerSubqueryRoot.get(projekt)),
						b.greaterThan(innerSubqueryRoot.get(versionsdatum), outerSubqueryRoot.get(versionsdatum))
					))
			    ))
		    )			  		    
	    );	    
	};
    }

Using this with Spring Data Repositories and specification makes JPA actually fun. But with jOOQ i can write it down like i would in SQL:

private static final Condition IS_ACTIVE_CONDITION = 
	exists(
	    select(val(""))
	    .from(outer)
		.join(LIEFERANGEBOTE)
		    .on(LIEFERANGEBOTE.LIEFERANGEBOTS_ID.eq(outer.LIEFERANGEBOTS_ID))
	    .where(
		    outer.PROJEKT_ID.eq(p.ID)
		.and(LIEFERANGEBOTE.ABSCHLUSSDATUM.isNotNull())
		.and(not(exists(
		    select(val(""))
		    .from(inner)
		    .where(
			    inner.PROJEKT_ID.eq(outer.PROJEKT_ID)
			.and(inner.VERSIONSDATUM.gt(outer.VERSIONSDATUM))
		    )
		)))
	    )
	);

Lukas promotes jOOQ for that kind of usage very well. But i say, it’s the simple things. I cannot only write elaborate queries, I can also write down what i want to select. jOOQ doesn’t try to be a mapping from a relational world into the slices of my application, it just maps tables and their columns 1:1. It’s up to me what i select. I could achieve this with native or JPQL queries as shown here, but than what’s the point of mapping all those entities anyway (to be honest, i’ve already done this on several occasions)? Another solution would be the new entity graphs but than i end up with either half-empty entities or getting nice surprises from lazy loaded associations.

What every JPA solution has in common, at least to me, is the fact that one ends up with one big package containing pretty much every entity there is. To create complete mappings from the relational into the object oriented world those entities depend on each other and i cannot slice it the way the application works.

You might say that this persistence package is analogue to the generated jOOQ tables and records, but i think they are quite different. The generated tables and records are mere means of accessing the same thing in the database, not more but also not less. Building a full fledged mapping is a lot more and implicates a lot more.

Not being forced to put effort into defining a logical and accurate class hierarchy to work with JPA but instead modeling and filling DTOs and business objects right from the database in a way that fits architectural slices of an application gives back a lot of freedom for writing cleaner and easier to understand applications.

| Comments (11) »

23-Sep-15


jOOQ and Spring: Manage your RecordMappers as @Components

Lately i’ve been evaluating jOOQ as a core database tool for ENERKO Informatik. Though i’ve got quite some experience (and good experience!) with Hibernate and Spring Data JPA, we have some projects around that are quite old but not outdated. They are in need for an UI/UX and some architectural make over, but the data model is mostly not but has never been designed with an ORM in mind. All that will be the topic of a later post, as I’m not done with my evaluation.

We will be using jOOQ as part of a Spring / Spring Boot project, so @petrikainulaines post Using jOOQ With Spring is of quite some use and i intend to add some info as well.

jOOQ provides several basic but quite functional ways to map records into POJOs as described here, but that’s pretty much it. jOOQs primary goal isn’t defining a new ORM, but the best way to write SQL in Java. Playing around with my data model, i really start liking it. Instead of defining multiple entity graphs, i can select the columns, children and everything i need the way it is meant to be and build my DTOs the way i want it. Enter RecordMappers for creating complex POJOS from records. If you don’t want to roll your own RecordMappers, there are quite a few out there .

Here is a super simple RecordMapper, that does pretty much nothing apart from setting an attribute:

import de.enerko.ensupply.db.tables.records.AnwenderRecord;
import org.jooq.RecordMapper;
import org.springframework.stereotype.Component;
 
@Component
public class AnwenderRecordMapper implements RecordMapper<AnwenderRecord, Anwender> {
    @Override
    public Anwender map(AnwenderRecord record) {
	final Anwender rv = new Anwender();
	rv.setName(record.getName());
	return rv;
    }
}

Notice the @Component annotation, which makes the bean a Spring Component. Alternatively it can be configured through plain Java or even XML configuration.

Enter my RecordMapperProviderImpl

What does it do? It retrieves a map of all beans implementing the RecordMapper interface and searches for the bean whose E type parameter (which isn’t erased when inheriting a typed interface like shown above) matches the target type.

I even wanted to compare the RecordType, but that type parameter is erased at runtime and so i’m basically comparing org.jooq.Record with itself. An API method to retrieve this would be nice, hint,hint, Lukas ;).

You may notice the @Cacheable annotation: If configured correctly (in Spring boot, just throw @EnableCaching at your Application class), Spring will cache the outcome of the annotated method and so preventing several expensive type lookups (which will be of some importance when mapping more than a handful of records).

Thanks to @thomasdarimont i got rid of the ApplicationContext dependency and @olivergierke was so kind about pointing me to ResolvableType so that i only depend on Spring and jOOQ.

The RecordMapperProviderImpl is registered with the jOOQ configuration as follows:

@Bean
public org.jooq.Configuration jooqConfig(
	    ConnectionProvider connectionProvider,
	    TransactionProvider transactionProvider, 
	    ExecuteListenerProvider executeListenerProvider,
	    RecordMapperProvider recordMapperProvider,
	    @Value("${jooq.renderFormatted:false}")
	    boolean renderFormatted
) {
	final DefaultConfiguration hlp = new DefaultConfiguration();
	return hlp
		.derive(hlp.settings()
			.withRenderFormatted(renderFormatted)
		)
		.derive(connectionProvider)
		.derive(transactionProvider)
		.derive(executeListenerProvider)	
		.derive(recordMapperProvider)
		.derive(SQLDialect.ORACLE);
}

(Bye the way, this will be done automatically in upcoming Spring Boot 1.3 given RecordMapperProviderImpl is an @Component like in the example).

If everything works well, expect some jOOQ and SQL content coming soon.

Update:

See my tweet, composing Record Mappers is really simple using that technique:

import de.enerko.ensupply.db.tables.records.AnwenderRecord;
import org.jooq.RecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class SpecialRecordMapper implements RecordMapper<Record, SomeObject> {
    private final AnwenderRecordMapper anwenderRecordMapper;	
 
    @Autowired
    public SpecialRecordMapper(final AnwenderRecordMapper anwenderRecordMapper) {
        this.anwenderRecordMapper = anwenderRecordMapper;
    }
 
    @Override
    public Anwender map(Record record) {
	SomeObject s = new SomeObject();
	// Do other mapping stuff
	s.setAnwender(this.anwenderRecordMapper.map(record.into(AnwenderRecord.class));
	return s;
    }
}

| Comments (2) »

09-Sep-15