The power to say no

One of the most important things we can do is to say no. A lot of things arise in work, in life. And the hardest thing is to sometimes say no. To indicate this shouldn’t be done. To voice our objection. Not argue, just say no.

Since Berlin, I have been working on adding Affordances to Spring HATEOAS. We’re talking a feature branch that has over 200 commits from the original author. The effort was pursued a couple years ago. It stalled out because no one on the team had time to champion this effort. Another team of developers actually forked the branch and added more. Finally, I joined earlier this year and started reading this vast sum of new code.

And I read, and read. And read. And. Read. We’re talking three months of reading, editing, polishing, changing, and rebasing. Did I mention reading?

So earlier this month, Oliver and I have a Google Hangout code review. I have pushed this code as far as I can. I have polished as much as possible. But when it comes time to defend it before my manager, one who maintains almost as high of a coding standard as Juergen Holler, things quickly fall apart.

“I just see piles and piles of code,” Ollie said. And I nodded along. He was right. I didn’t want it to be true, but it was clear. He quickly spotted my sample where both a PUT and a PATCH were shown, the outcome that one method required every parameter, while the other required none.

“Couldn’t we spot the method and flip that bit automatically?” he asked. More nodding from my end. He was gosh awful right. And I knew this current branch of code was never getting near the master branch.

So what did we do with three months of effort? We regrouped.

“What if we start clean? The serializers for HAL-Forms are solid. Why don’t we work on a fresh Affordance API, and see how much of Spring MVC we can leverage to find the other details?” I said.

And here I am, two weeks later, closing in on a feature branch. It includes HAL-Forms mediatype plus a VERY lightweight API for defining an Affordance.

This small bit of Spring MVC + Spring HATEOAS code is lifted from a test case.

It’s the handler for a GET /employees/{id} call.

It creates two links: self and employees.

Using a new method (withAffordances) and a new utility method (byLink), it has access to everything about this the PUT and the PATCH operations, and can glean the attributes needed to run those two methods.

And it doesn’t involve piles and piles and piles of code. I think I spent two days trying to model where these “Affordances” would live. (Ended up in the Link itself, since a Link can have one or more). I spent another day or two digging through the method invocation to build these links, and harvested extra Spring MVC details, like the route, the incoming request body’s type, and a little more.

I think I’ve spent maybe two days ensuring these bits of code don’t intrude on each other. For example, the code that reads Spring MVC annotations isn’t part of the Affordance interface. That will make it easier to write a JAX-RS version down the road. We also need to support Spring WebFlux at some point as well. And the Affordances stuff cannot leak into the mediatype.

So focusing on getting single resource, collections of resources, and pages of resources working has taken a total of maybe two weeks. (Today was the day I got pages working).

Oliver is quite excited about this. As am I. This will set the pace for implementing other hypermedia types. We currently have HAL and are adding HAL-Forms. Coming: Uber, XHTML, and SIREN. And when these arrive, they will become available to Spring Data REST.

Additionally, my handful of PRs I worked on over the past three months are ALSO getting reviewed, so there is indeed a lot of motion of Spring HATEOAS.

I’m really happy Oliver say “no”. Remember, it’s your option to say as well. Just be ready to defend it with all your might.