Category Archives: software

How TDD is wrong

I’m a pretty big test advocate. After all, it’s in my profile. So how can I say that TDD is wrong?

“Test-bitten script junky…” — opening of my profile

 

The “test-bitten” means I’ve been bitten by the automated testing bug. In a previous post, I mentioned having built the equivalent of a CI solution early in my career without knowing it. So how can I advocate such a heretical point of view?

The answer is subtle. To me, the benefit of automated testing is in having the testing and automating it.

  • Nowhere do I see primary benefit in writing the test first.
  • Nowhere do I see it better to write the test then write the code that solves the test.

Transitioning into my current role on the Spring team has moved me into the land of framework design. Building frameworks is quite different than end-user apps. That’s because the code you write is meant to serve not one but many. And in the case of Spring, we’re talking millions of developers (no exaggeration).

When serving this many people, you are building APIs, implementations of APIs, and ensuring that all kinds of scenarios don’t break that API. So I often have to start writing the API first. I try to create some fields. Add the accessors I need. Try to chain stuff together. And then I begin to write test cases that poke at it.

Several Spring projects also use Project Lombok. This is a really neat toolkit that I’ve known about for years, but only in the past two years have I truly come to appreciate it’s power. It makes it possible to stop writing getter/setters/equals/hashCode functions, customize visibility of accessors, define data classes, value classes, builders, and other stuff. All with a handful of easy-to-read annotations.

Trying to write a test case and then writing a Lombok-based class is ineffective. I’d rather create the class first and then use it’s pre-packaged structure in the unit test. Using Lombok in this way ensures a lot of very consistent structure that makes the overall API easier to consume. For example, it’s Builder annotation produces an API that looks like this:

This example is the builder I defined for the hypermedia format of Collection+JSON. It lets you lay out all the parts of a CollectionJson record, which is then serialized into JSON. The class behind it looks like this:

This class has several things, so let’s take it apart.

  • @Data and @Value create setters and getters, along with equals, hashCode and toString methods. This is the core for a Java object, but not the bits directly needed for a builder.
  • @Builder creates the fluent builder shown earlier with collectionJson the static function to create a new instance of this class.
  • @JsonCreator is simply used to connect Jackson to this class when it comes to deserialization.
  • And because the Item class is also a builder, I have item() as a convenience method to dive into this “sub” builder.

That’s it! This class is highly coherent because there is little “code” as in logical stuff being done. Instead, it’s mostly declarative. This class isn’t buried in logic, because it’s focused on defining a data model.

I can’t imagine noodling my way through this in a unit test and then trying to bend Lombok to support my test case. Like I said, it’s easier to define all the properties (version, href, links, and items), then flagging it as a Builder, Data, and Value class. Go into the unit test code, and start using it. Avoid much heartache.

And because I can still submit pull requests with gobs of test cases, achieving 100% coverage of things, I see little value in this “test first” approach advocated by TDD.

So…am I wrong? In what way? Jump in on the comment cause I’m dying to hear.

Why every press needs a code monkey

It’s not secret that I’m writing a novel. (If you HAVEN’T heard this, then I’m just not communicating very well!) It’s scheduled for release in March with a relatively small press called Clean Reads.

And its owner wears many hats. An author herself, the owner of Clean Reads is also an editor, content manager, graphic designer, mother, aunt, and many other things. But I think you get the idea. She is fundamentally running the press herself with a handful of freelance editors and cover artists.

Anything missing in there? Oh yeah. Her press has a website. Did I mentioned she’s a code geek? A bit burner? A web designer? No? Well that’s because she isn’t. So what has happened because of this? What happens to every business caught up in the 21st century stuck with 20th century business practices.

She has been doing the best she can with Facebook, Twitter, and Instagram. Ahh, the good ole social media triumvirate. We keep hearing word that you must get on social media if your business is to succeed.

Well that’s one big lie.

Social media is a channel to reach people, but since the inception of Facebook, it has steadily gone down hill. How? In the beginning, when someone “liked” your group, they would then get EVERYTHING you posted. Today? They might get 10%. Unless you pay Facebook a little deneiro.

People that built up empires of followers on Facebook years ago, watched their sales plummet as they could no longer REACH their followers. That is, until Facebook started extorted…err…charging money to reach YOUR followers. Evidence that they aren’t YOUR followers but Facebook’s.

My wife’s research into social media revealed one author that took a three month break from writing. To do what? That’s right, focus on facebooking, tweeting, and instagramming. And in three months of effort, got maybe a 30% reach of her social media followers. Yikes!

This is why it is SO important to build a mailing list. A website you control and a mailing list that reaches EVERYONE is the most important thing you can build for your business. And if you don’t know how to stand up a website and configure it to harvest emails, you will be left in the cold.

At the Kentucky Christian Writer’s Conference, I met my publisher face to face. We chatted over lunch. And in the midst of that, is when I learned that Stephanie needed help raising her website from the ashes of a previous outage. They say never pass up an opportunity, so I haggled out a deal where she’d remove a certain criteria she had for going to paperback, and I’d get her website operational. With a handshake, I got on the ball.

Since then, we have loaded over four hundred backlisted titles along with cover art and e-books. Visit the site and you can BUY books. Join our newsletter (trust me, you’ll get the opportunity if you visit), and you’ll get a super secret coupon code to buy ANYTHING at 20% off.

I’m not here so much to hawk that site, as to instead hawk the idea that when you form a business, whether it’s a publishing press or ANYTHING ELSE, you need SOMEONE that can do this stuff. I know WordPress. I’ve used it to run my blog for years. It’s not perfect, but it gets the job done. With a little sweat equity and some time reading tips and tricks, you can really put out a decent store for your business.

If you are even THINKING of running a business in the 21st century you need to:

  • Learn how to standup and run a WordPress site (an independent consultant could cost you $10,000 easily)
  • Start building a newsletter
  • Use Facebook and Twitter. Don’t let them use you. The idea is to make money for YOU, not be the one making money for THEM.

Stay safe out there!

OOP is dead, long live OOP

Raise your hand if you remember the golden hammer of Object Oriented Programming. You know, where you only have to code something once and then reuse it in all your subclasses? Remember those days?

Maybe this is what they still teach in dusty lecture halls amidst today’s Computer Science departments. But if you have spent any significant time coding in the trenches, you will have come to realize the lie that this mantra is.

You see, grandiose hierarchies of objects over time become nigh impossible to manage. At a certain point, one more subclass bolted onto the grand structure is deemed impossible and you must fork the solution. No, there is a different structure out there that we must adopt. And Spring is the platform that carries its banner.

Interface Oriented Programming. Let’s call it IOP since there aren’t enough acronyms in our industry. IOP is the premise that different slices and layers should talk to outsiders through a nice, clean interface. The backing service on the other side should provide a concrete implementation, but the caller need not know about it.

Why do I mention Spring as the champion of IOP? Because Rod Johnson’s foray onto the  Java scene was to craft a dependency injector whereby this interface-based contract could be satisfied. Before I learned of Spring, the concept of Java interfaces was foreign. Sure they were mentioned in my college textbook Java in a Nutshell (dating myself?) but I saw little value in using them. Why?

Because when you are “newing” everything yourself, there appears little value in defining an interface and then assigning the object to it. You already know what is! What is to be gained from all the extra typing? But delegate that task to a DI container, and suddenly the cost vanishes. Expressing dependency graphs between beans with interfaces becomes much smoother when the container takes over the job of creating everything.

This goes along with the Liskov Principle where you can plug in any implementation without knowing what it is. Now sometimes people drag out the old square-is-a-rectangle example. I hate that one because geometry is a terrible domain to model semantic software concepts.

Digging in, interfaces don’t have to be complex. Instead, think of a handful of “getters” and go from there.

This fragment is part of an ongoing effort to add Affordances to Spring HATEOAS. Since we might support multiple web frameworks, having a clean, unencumbered interface is critical for getting started. It also helps avoid saddling the interface with details from Spring MVC, Spring WebFlux, or JAX-RS. Instead, this interface avoids all of that, forcing the concrete details to be nicely contained apart from each other.

Abstract classes and long hierarchies are often tricky to evolve over time, so I try to dodge that as much as possible. Composition of objects through IOP-driven strategies tends to be more amenable to change. Having said all that, what happens when you need this?

This is ONLY an abstract class because the project is currently on Java 6 and we can’t plugin a default implementation for supports(). With Java 8, this whole thing can be rolled back into an interface. Abstract vs. default interface methods aside, this is the NEW OOP. Do as much as you can to code 1 interface-to-many classes, avoiding intermediaries. Sometimes it’s unavoidable, but don’t give up too fast.

Let IOP be your OOP.

And the more you learn about the whole code base, be willing to revisit some of those hierarchies and see if you can’t “move around” stuff to get away from the hierarchies. You might be surprised at how perky your code becomes. Some of those requested features might suddenly seem possible.

The Power of REST – Part 1

I was kind of shocked when I saw Yet Another Posted Solution to REST. I sighed and commented, and drew the ire of many. So I figured this might be a good time to gather some thoughts on REST.

The article starts by criticizing REST and offering their toolkit as the solution. What’s really funny, is that the problems they ding are not RESTful issues.

REST requires lots of hops

Let’s start with this one:

As you might notice, this is less than ideal. When all is said and done we have made 1 + M + M + sum(Am) round trip calls to our API where M is the number of movies and sum(Am) is the sum of the number of acting credits in each of the M movies. For applications with small data requirements, this might be okay but it would never fly in a large, production system.

Conclusion? Our simple RESTful approach is not adequate. To improve our API, we might go ask someone on the backend team to build us a special /moviesAndActors endpoint to power this page. Once that endpoint is ready, we can replace our 1 + M + M + sum(Am) network calls with a single request.

This is the classic problem when you run into when fetching a 3NF (3rd normal form) data structure served up as REST.

Tip #1: REST doesn’t prevent you from merging data or offering previews of combined data. Formats like HAL include ability to serve up _embedded data, letting you give clients what they need. Spring Data REST does this through projections, but you can use anything.

In fact, server-side providers will probably have a better insight into exactly the volume of traffic fetching such data before clients. And through the power of hypermedia, can evolve to add links to the hypermedia without breaking existing clients. Old clients can do multiple hops; new clients can proceed to consume the new links, with full backwards compatibility.

REST serves too much data

If you look closely, you’ll notice that our page is using a movie’s title and image, and an actor’s name and image (i.e. we are only using 2 of 8 fields in a movie object and 2 of 7 fields in an actor object). That means we are wasting roughly three-quarters of the information that we are requesting over the network! This excess bandwidth usage can have very real impacts on performance as well as your infrastructure costs!

Just a second ago, we complained that the REST API was serving up too little data, forcing us to take multiple hops. Now we are complaining that it serves too much data and is wasting bandwidth.

The example in the article is a bit forced, given we are probably talking a couple tweets worth of data. It’s not like they are shipping 50MB too much. In fact, big volume data (images, PDFs) would best be served as links in the hypermedia. This would let the browser efficiently fetch a linked item once, and lean on the browser’s cache.

But I sense the real derision in the article is because the endpoint isn’t tailored to the client’s precise demands. No, the real example here is to illustrate a query technique on the client.

Just put SQL in the client already!

Wouldn’t it be nice if we could build a generic API that explicitly represents the entities in our data model as well as the relationships between those entities but that does not suffer from the 1 + M + M + sum(Am) performance problem? Good news! We can!

With GraphQL, we can skip directly to the optimal query and fetch all the info we need and nothing more with a simple, intuitive query.

So now we get to the real intent of the article: introduce a query language. Presumably solving REST’s straw man “problems” (which it doesn’t).

If you want to write a highly detailed query, just open a connection the data store and query directly. That’s what query languages are for. Why invent something that’s weblike, but really just Another Query Language?

What problem are you solving?

GraphQL takes a fundamentally different approach to APIs than REST. Instead of relying on HTTP constructs like verbs and URIs, it layers an intuitive query language and powerful type system on top of our data. The type system provides a strongly-typed contract between the client and server, and the query language provides a mechanism that the client developer can use to performantly fetch any data he or she might need for any given page.

This query technology may be quite handy if you must write intense, focused queries. If cutting a couple text-based columns makes that much difference, then REST may not be solution you seek. (Of course, at that point why not just have your JavaScript frontend open a SQL/MongoDB/Neo4j connection?)

What does REST solve? REST solves the brittle problem that arose with CORBA and SOAP.

REST makes it possible to evolve APIs without forcing you to update every client at once.

Think about that. When web sites make updates, does the web browser require an update? And why?

It’s no light feat of accomplishment. People were being beaten up left right as APIs would evolve. Updates were tough. Some clients would get broken. And availability is key for web scale business. So adopting the tactics that made the web resilient into API design sounds like a keen idea to try.

Too bad not enough people actually KNOW what these concepts are, and press on to criticize REST while offering “fixes” that don’t even address its fundamentals. The solution served in the article would put strong domain knowledge into the client, resulting in tight coupling. REST doesn’t shoot for this.

Am I making this assessment up?

This “virtual graph” is more explicitly expressed as a schema. A schema is a collection of types, interfaces, enums, and unions that make up your API’s data model. GraphQL even includes a convenient schema language that we can use to define our API.

Agreed. Continuing with more tight coupling instead of letting server side logic remain server side would align with SOAP 2.0, in my opinion. And it’s something I don’t much care for.

To dig in a little more about how REST makes it possible to evolve APIs with minimal impact, wait for my next article, The Power of REST – Part 2.

The myth of polymorphism

I remember reading about polymorphism for the first time. I was in high school, and boy it sure looked cool! Too bad I didn’t realize that the myth of polymorphism was a bunch of poppy cock.

You see, polymorphism never seems to be presented in its real state. Instead, we get this goofy, toy-app type presentation. Does Shape -> Rectangle -> Square ring a bell?

The fallacy of geometrical shapes being polymorphic

One of the simplest ways people seem to introduce polymorphism is using geometric shapes. We all know that a Square is a Rectangle. We covered that nicely in geometry, right? Problem is, geometry doesn’t equal software.

When discussing things in light of geometry, the reason we value this relationship is because we are looking at things like angles, parallelism, vertices, and intersections. Hence, squares carry all the attributes of rectangles. They simply have the same width and height.

But software isn’t geometry. The things we construct we must also interact with. The shapes must afford us operations to grab them, interrogate them, draw them, and manipulate them. A rectangle has two attributes: width and height. A square has one: width.

If we grabbed a square, set its width, then set its height, the assumptions of what would happen is unclear. Should a square morph into a rectangle? Or should setting the height induce the side effect of also updating the width? Either way is bad form. Hence, its best to break apart this faulty geometric relationship and realize that squares are NOT rectangles.

The fallacy of inheriting behavior

So shaking off the trivial example of geometric shapes, another common example is to talk about the glorious ability to reuse code. With polymorphism, it will be SO easy to code something once, and then reuse it across dozens if not hundreds of classes! And with late binding options, gobs of 3rd party libraries can go forth and reuse your code.

The problem is, no programming language has adequately been invented to gather ALL the semantic nuances of code. As more and more classes extend a given class, they all either realize EXACTLY what the abstract parent class does and agree with it, or they discover some new wrinkle not quite handled. The API may be supported, but some underlying assumption is buried that requires an update.

As the tail of inheritance grows, maintainers are less likely to accept new changes to the shared code. The risk of breaking someone else grows, because everyone knows not the ENTIRE nature of the code can be captured.

Some of the avenues to remedy this involves opening up the API a bit more. Perhaps a private utility method is needed by a new extender. But opening it up introduces more maintenance down the road. Or more opportunities for others to abuse things that used to be kept tightly controlled.

History has proven that composition beats inheritance for sustainability. Raise your hand if maintenance, not new development, doesn’t encompass much of your work.

The alternative are more sophisticated languages where you can capture more of the concepts. Yet these languages come across as too complex to many, arguably because CAPTURING all semantics is inherently challenging. And more often than not, we don’t KNOW all these semantics on the first round.

The myth of polymorphism vs. the reality

One thing that has emerged is programming to interfaces. Interfaces provide a nice contract to work against. Naturally, we can’t capture everything. But at least every “Shape” can  institute the defined methods. In Java, interfaces can be combined, allowing multiple behaviors to be pulled together.

So when it comes to abstract and refactor, think about extracting interfaces when possible and delegating solutions.

Strangely enough, despite my consternation with static variables, I’ve come to appreciate static methods in the right scenario. Factories that support interfaces can be quite handy dandy. But a well modeled, inheritance hierarchy is to hard to accomplish. If possible, try to avoid multiple layers, and see if it’s not possible to extract share code into various utility classes.

And when the entire hierarchy is nicely contained INSIDE your framework, and not as an extension point to consumers, the fallacies of polymorphism can be contained. But watch out! It takes much effort to put this together. Never think it will be easy.

Of course, I could be entirely wrong. If you have some keen examples, please feel free to share!

Happy coding.

Why take a break?

Good developers take breaks. But why? Last night, I attended a men’s session where two very different people talked on stage about very different breaks. The first was a pastor who was granted a six month sabbatical. The second was someone that was fired, and instead of lunging for the next job, spent time evaluating things carefully. As I listened, it made me reflect upon my own discoveries about taking breaks.

Why do we need breaks?

To be honest, it’s quite easy to burn yourself out. Maybe when you’re a bit wet behind the ears and single, not so much. I once worked extensive hours (despite not getting paid overtime), and I don’t regret that.

But today I can’t do the same thing. I have three kids and many other responsibilities that preclude me from working ALL THE TIME. Well, a big difference between now and then, is that back then, I needed a lot of “tinkering” to figure things out. I was short on experience, but long on drive. And working extra hours helped me learn a lot of valuable lessons.

Today, the valuable lessons are taking breaks, and letting my subconscious continue chugging away. Even today, I’m working on a major review/refactor/rebase task that has already cost me two weeks and will probably cost a couple more. Yet I don’t dread this effort. In fact, I’m not trying to rush it. Because the hours I’m away from my laptop (like now), my mind is still noodling things out. And when my fingers rejoin the keyboard, I feel like my knowledge of this branch is growing at a comfortable pace. If I tried burning ten hours a day, I’d burn out and torch it all.

But by letting my family pull me away, and focus on other important things, I am stopped from burning out. And I can avoid spinning my wheels in the mud of frustration. In the past five years, I feel as if my productivity has actually increased, because I am working smarter not harder.

What good do breaks do?

Let’s just jump right in and state something critical – your work isn’t everything. When you pass from this world, people are less likely to remember the code you wrote, and instead remember the impact you made on your children, your spouse, and your community.

I remember a graphic that came out of Microsoft showing how you could access every aspect of your job from everywhere – a kids soccer game, waiting for an appointment, during breakfast, etc. 37Signals released a mocked up variant with the same style, only they dubbed it Work Can Wait (which you can see linked her). The thing basically stresses the importance of having a life.

But in addition to balancing work and life, I’ve discovered that my work actually flourishes when I get away from it. I once sat in on a talk by Dr. Venkat Subramaniam, who described that classic software eureka moment of realizing the answer to your problem you battled all day. The next morning, in the shower. I’ve experienced that a fair number of times, moreso since I started taking more breaks.

I enjoy, on occasion, merging a Github pull request after hours. But I don’t go out of my way to do that. It’s usually something small, like a typo in a guide. I enjoy being able to shuffle that off my plate in a bit of idleness. But pulling myself AWAY from the keyboard sometimes forces my mind to assess what just happened, and what’s coming next. Seeing that I have less time to spend, my brain hammers out certain details to make better usage of our next keyboard session. And I sincerely believe I code with higher quality because of this.

Try it. You might be surprised.

I’ll close by sharing a reflection I received from Mark Fisher, founding member of the Spring team. He once mentioned that if he had been forced to work nose to the grindstone, and hadn’t taken all the various walks, and simple “think about it” moments, Spring Integration may never have happened. Not everything is a burn-baby-burn coding moment.

Happy coding!

Guten Tag Deutschland. Ich bin da!

I just arrived in Germany for our big Spring Data summit. Our team is having a get  together to do some planning and scoping of work for the next year. And I couldn’t be more excited.

I arrived at 7:00 am local time, and waited two and half hours to discover the airline had lost my bag. But pay it no mind. I packed the critical in my carry on so with paperwork filed, it’s no sweat. The fun part (so far) was having the leverage my German to interact with my taxi driver, who spoke hardly any English.

Something i was able to contemplate while traveling, is that one of the biggest things I missed while working on Spinnaker was the jürgenized code base of Spring. The clean, elegant nature of all the portfolio projects really gives me a warm fuzzy.

Its hard to explain if you haven’t seen clean code before. But having a strongly enforced clean, consistent coding policy eases the mind. When we write code, we need to understand it. Sifting through inconsistent spacing, sloppy names, tabs AND spaces, and other aspects of code slows down the brain, making it hard to digest the functional aspects.

My father-in-law once shared that driving while it’s raining tires you out faster. He once had to drive at night through a lot of rain and it wore him out. The same can be said for sifting through sloppy, inconsistent code.

So this week I celebrate being back amongst my Spring Data mateys as he continue hammering out what has to be one of my favorite umbrella projects. Applying the concepts of the Spring programming model to Data management.

Cheers!

How to write a tech book, or how I stopped worrying and learned to love writing

I just sent in the last chapter of Learning Spring Boot 2nd Edition’s 1st draft. And my brain has collapsed. I’ve been working for several months on this 10-chapter book that embraces Spring Boot 2.0 and reactive programming. There are several books out there on reactive programming, but I believe this will be the first to hit the market about Project Reactor.

I’m not done, not by a long shot. I told my publisher that we’d need at least one big round to make updates to ALL the code, because I started writing when not everything was in place. And it’s still true. But editing, polishing, and updating an existing repository of code and manuscript is easier than creating one out of thin air.

I wanted to write just a little bit about how I approaching writing something like this. Maybe you have been thinking about writing a book yourself, and your curious what goes on. This isn’t the only, but it’s the way that works for me.

Tools

Laptop on a work table with DIY and construction tools all around top view hobby and crafts concept

To write a book, you need a mechanism to capture prose and code. For fiction, I use Scrivener, but when it comes to technical writing, where the code, screenshots, and text are tightly integrated, I use Asciidoctor. With Asciidoctor, the overhead of a word processor is removed, and instead I can focus on pure content.

Also, using Asciidoctor lets me pull in the code to generate the manuscript sent in to my publisher. This way, I have Sublime Text in one window viewing the source prose and IntelliJ open in another viewing the source code. To top it off, I have a Ruby guardfile configure to constantly regenerate an HTML proof of the chapter I’m writing with it refreshing via LiveReload in my browser.

This combination gives me a quick feedback loop as I write.

What to write

This may be the biggest hurdle to some. When you’ve picked the technology, setup your tools, and finally have the editor opened up, what do you type in that black, blank screen?

Waiting for magical words to arrive? Or perhaps you hope elves will scurry in and leave something? Nope. This is where the rubber hits the proverbial road and you have to push yourself to start typing.

What do I do? I actually start earlier than that. From time to time, I have a crazy idea about something I want to show to an audience at a conference. Some demo I want to give with a few pieces of the Spring portfolio. I began to noodle out code to make that happen. Once, I asked “can I snap a picture of the audience and upload it from my phone to a webpage the audience is watching on the overhead?” Thus was born my Spring-a-Gram demo.

That demo has morphed many times to the point that I have built a full blown, cloud native, microservice-based system. And guess what. It’s the system we get to explore in Learning Spring Boot 2nd Edition.

So when I sit down to write a chapter, I first start writing the code I want to walk through. Once it’s humming inside my IDE, I start to typeset it in Asciidoctor. And pages of code fragments, I began to tell a story.

Weaving a story

When writing technical articles, getting started guides, and books, everything is still a story. Even if this isn’t a novel, it’s still a story. People that grant you the honor of reading your work want to be entertained. When it comes to tech work, they want the ooh’s and ahh’s. They want to walk away saying, “That was cool. I could use that right now.”

At least, that’s how I read things. So my goal when I write is to make it fun for me. If it’s fun for me, I trust it will be fun for others.

If I sift through a chapter, and it’s just a boring dump of code, then it’s sad. And that’s not what I want. I can’t promise that all my writing has upheld this lofty goal. But it’s my goal nonetheless.

So oftentimes, I will typeset the code, hand some descriptive details around the code, then read it again, top to bottom, and add extra stuff. Paragraphs talking about why we’re doing this. Mentioning tradeoffs. Issues that maybe exist today and where we have to make a choice. Ultimately, understand not just what the code does but why it does it this way. And what other options are out there.

Letting go

At some point, after all the writing and polishing and fine tuning, you have to turn in your work. I don’t know if there is ever a time where I’m 100% satisfied. I’m kind of picky. But the truth is – you’ll never find every typo, every bug.

My code fidelity is much higher ever since I started using Asciidoctor. But stuff happens. And you have to be happy turning in your work.

You see, if you’ve acquired enough skill to sit down a write a book without someone leaning over your shoulder and coaching you, you might have a lot of good value other developers seek. Eager coders will be able to read what you wrote, look past small mistakes, and most importantly, grok the points you make. That’s what is key.

And one thing is for certain – writing makes you better. I have found that any gaps in my own understanding of certain parts of code lead me to chase down and grasp those bits. And then I want to share them with others. Which is what writing books is all about.

Happy writing!

Layering in new behavior with React

I’ve talked in the past how I like the approach React leads me to when it comes to building apps. How does such grandiose talk play out when it’s time to add a new, unexpected feature? Let’s check it out. I’ve been building an installation app for Spinnaker, and one of our top notch developer advocates gave it a spin.

Results? Not good. Too many presumptions were built into the UI meaning he had no clue where to go. Message to me? Fix the flow so it’s obvious what must be done and what’s optional.

So I started coding in a feature to flag certain fields REQUIRED and not allow the user to reach the installation screen without filling them out. Sounds easy enough in concept. But how do you do that?

With React, what we’re describing is an enhancement to the state model. Essentially, keep filling out fields, but earmark certain fields as required, and adjust the layout of things to show that, while barring other aspects of the interface in the event those same fields aren’t populated.

So I started with a little bit of code to gather a list of these so-called required fields, and it looked like this:

If you have done any React programming, assigning something via this.state[…] = foo should set off bells in your head. You always, always, ALWAYS used this.setState(…). So what’s up?

Rules are rules until they aren’t. This is a situation that defies the concept. I don’t WANT to set the state such that it triggers a ripple through the DOM. Instead, this code happens right after the initial state model is initialized. And I’m setting it using values populated in the previous line, because you can’t initialize required, pointing at this.state.api in the same call the initializes this.state.api itself!

With this list of required fields setup, we can start marking up the fields on the UI to alert the user. I have a handful of React components that encapsulate different HTML inputs. One of them is dedicate to plain old text inputs. Using the newly minted required list, I can adjust the rendering like this:

Notice the little clause where it checks this.props.settings.requires.includes(this.props.name)? That is a JavaScript ternary operation that if true, returns the label with extra, highlighted text. Otherwise, just render the same label as always.

By applying this same tactic to the other React components I have for rendering each selection on the UI, I don’t have to go to each component and slap on some new property. Instead, the designation for what’s required and what’s not it kept up top in the state model, making it easier to maintain and reason about.

At the top of the screen is a tab the user clicks on to actually install things and track their progress. To ensure no one clicks on that until all required fields are populated, I updated that tab like this:

A little function that detects whether or not all required fields have been filled out is checked, and if so, renders the HTML LI with its onClick property filled out with the handler. If NOT, then it renders the same component, but NO SUCH onClick property is present, meaning it just won’t respond.

This is the nature of React. Instead of dynamically adjusting the DOM model, you declare variant layouts based on the state of the model. This keeps pushing you to put all such changes up into the model, and writing ancillary functions to check the state. In this case, let’s peek at requiredFieldsFilledOut:

This tiny function checks this.state.required, counts how many are “truthy”, and if the count matches the size of this.state.required itself, we’re good to go.

In case you didn’t know it, React encourages you to keep moving state-based functions up, closer to the state model itself. It’s super simple to pass along a handle to the function to lower level components, so they can still be invoked at lower levels. But anytime one component is trying to invoke another one in a separate part of the hierarchy, that’s a React-smell hinting that the functions should be higher up, where they can meet. And that results can trickle down to lower level components.

I encountered such a function stuffed down below in a lower level component. The need to trigger it sooner based on a change in the state had me move it up there. Now, when the Installation tab is clicked, that function is run, instead of waiting for the user to click some button down below.

Suffice it to say, I rehabbed the UI quite nicely. The thing is, with React it’s not hard to effect such change in a couple days, compared to the days or weeks of effort combined with testing it might have taken with classic manipulated-the-DOM apps, where you have to hunt down gobs of wired event handlers and find every little nuanced operation you coded to make things operate correctly.

Check out my @SpringData and @SpinnakerIO talks from SpringOne Platform @S1P

Recently, my latest conference presentations have been released. You are free to check them out:

In the Introduction to Spring Data talk, I live code a project from scratch, using start.spring.io, Spring Data, and other handle Spring tools.

In the Spinnaker: Land of a 1000 Builds talk, I present the CI/CD (continuous integration/continuous delivery) multi-cloud tool Spinnaker:

Enjoy!