Reading List

The most recent articles from a list of feeds I subscribe to.

jq

I rediscovered jq the other day, a little command line tool to format, read, and transform JSON from the command line.

Jq falls into one of my favorite categories of tools: the “simple and do one thing good” category—the Unix philosophy at its finest.

Pipe any JSON to jq. The first thing you’ll notice is the added syntax highlighting.

A curl request to the GitHub API

A curl request to the GitHub API piped through jq

Then, you can use a path syntax to query the JSON object.

Filtering a JSON object with jq’s path syntax

The path syntax supports arrays and deeply nested objects, and can even map data with a pipe operator.

Transforming a JSON object with jq’s path syntax

Installing jq on a Mac is as easy as brew install jq. Read the docs for further instructions and a detailed explanation of the path syntax.

Consistency

There are two bike stalls near my apartment. One is right in front of the door, the other around the corner. The one in front of the door is closest, so when I can, I store my bike there. However, most of the time that stall is full, and I need to go around the corner instead.

That’s fine. Until a next morning–when I’m still in a daze because I’m not a morning person–I take the walk around the corner, only to realise my bike was actually in front of the door. The day before was one of those lucky days I could store my bike in front of the door.

I quit using the front stall. The less choices I have to make, the more room I have for important things.

This mindset also affects the way I code. In a large projects we’re working on, we often need form request objects. Form request objects take care of validating a requests, before they enter a controller.

<?php
class UserRequest
{
public function rules()
{
return ['name' => 'required'];
}
}
class UserController
{
public function edit(
UserRequest $request,
User $user
) {
// …
 }
}

In this case, extracting that simple rule to a form request doesn’t really benefit us, so we can just inline the rules in a $request->validate() call.

<?php
class UserController
{
public function edit(Request $request, User $user)
{
$request->validate(['name' => 'required']);
// …
 }
}

However, I needed to make a conscious decision: “Should I extract these rules to a form request?” In this case it was obvious. In other cases, It’ll be obvious to use a form request object because I need to reuse the rules across multiple controllers. In the worst cases, it’s a 50/50 split, depending on my mood the rules will or won’t end up in a request object.

That’s why we’ve decided to always use form objects, no matter how small. It removes a decision point when writing, and more importantly when reading code. If we need to debug the validation rule, we know exactly where to expect it. No 50/50 chance to end up in the wrong place.

The less choices we have to make, the more room we have to focus on the important parts of our code.

Oh Dear redesign, Inertia & another book

Hi!

This month I’ve got updates on Oh Dear’s redesigned dashboard, new Inertia features, our second book at Spatie, and some more tidbits.

Oh Dear’s new dashboard

I redesigned the main Oh Dear dashboard. It had remained pretty much unchanged since Oh Dear was first released almost three years ago–time flies!

Here’s the before…

Screenshot of the Oh Dear dashboard before the redesign

…and the after!

Screenshot of the redesigned Oh Dear dashboard

I wanted to make it calmer. The old version screams at you when everything is fine, and screams even louder when something is on fire. Too. Much. Screaming.

The new dashboard increases the contrast between fine and fire with colored dots instead of badges. Problems are still highlighted making to make them stand out.

I used CSS grid to make all the check columns have the same size while allowing the site name column to grow. Consistent column sizes for all checks makes the new design look a lot more tranquil.

Inertia updates

We added a lazy props feature to Inertia last month. Lazy props allow you to load a page without including all data. For example, if you need to populate a dropdown, you can defer loading the options until the user is going need it.

There are a lot of interesting issues open in the repository to turn Inertia into a more powerful tool to build SPA-like experiences with instant load times. My favorites are local visits and inline visits. Fun things ahead!

Designing a second book

After Laravel Beyond CRUD, I designed another book: Front Line PHP. This time I used InDesign instead of Affinity Publisher. After I lost a lot of time in the last round when Publisher corrupted my file, I reconsidered InDesign. InDesign has more advanced features like better footnote management, and the possibility to export an EPUB file.

I shared a short Twitter thread with some design details.

PS: Use this link for a 20% discount on the book!

2020: The death of podcast listening

Overdramatic header, but true for me. Since I’ve been working from home, I haven’t been making time to listen to podcasts. I used to keep up during my commute, but I haven’t been able to fit them in my home schedule.

I miss Caleb and Daniel’s banter on No Plans to Merge. I haven’t even had the chance to listen to Full Stack Radio‘s new format with Jack. And there are so many others to catch up on…

2021: The calm before the newsletter storm

If I were to bet one thing for 2021, it’d be that paid newsletters are going to go big. Substack is becoming more popular by the day. Others including Ghost, Gumroad, and more are following suit with paid subscription features.

I’m seeing more and more quality, in-depth content land in my inbox instead of discovering everything through Twitter and RSS. I haven’t come this in my “Laravel filter bubble” yet, but I wouldn’t be surprised if newsletter-first starts getting traction there soon.

More on the blog

Not much apparently! Since the last newsletter, I only published two posts and a link.

Smalltalk

Being at home more often means more board games! I was looking for some fun games for lower player counts (2—3 players) so I asked Twitter.

Guided by the responses I ended up buying 7 Wonders: Duel, and Wingspan (what a beautiful game!) Other games I’ve been enjoying are Terra Mystica, Carcassonne, Kingdomino, and (as always) Catan.

On the horizon

What’s next? Tough question. I’m really into things like knowledge management, effective communication, and product management these days. I want to start sharing more about that, but haven’t decided how or where yet. We’ll see.

Until the next issue,

Seb

When to add types and when to infer in TypeScript

Type inference is the ability to derive types from other pieces of code. TypeScript’s type inference is very powerful, even a minimal amount of typing adds a lot of assertions.

Just because you don’t need to add types, doesn’t mean you shouldn’t. This is how I decide when or when not to explicitly add types in TypeScript.

In this first example, the least amount of types possible were added: the parameters.

function divide(a: number, b: number) {
return a / b;
}
const result = divide(10, 2);

TypeScript infers that result is a number despite not adding a return type to divide, or a type declaration to the result variable.

TypeScript knows that a / b will return a number, so divide returns a number. TypeScript knows that result has the same type of whatever divide returns, which is a number.

A more explicit version would have a lot more number.

function divide(a: number, b: number): number {
return a / b;
}
const result: number = divide(10, 2);

When do I add types, and when do I infer? I follow one simple rule: Add types to all function declarations.

My version of the snippet lands somewhere between the two.

function divide(a: number, b: number): number {
return a / b;
}
const result = divide(10, 2);

I type function declarations for two reasons: readability and contract.

Readability: by typing the declaration, I know exactly what to expect of the function without looking at its body.

While we could assume this will return a number, we can’t be sure. And assumptions are exactly what we’re trying to avoid by using types.

function divide(a: number, b: number)

Contract: by typing the declaration, I’ll catch unexpected types in the function body sooner.

This would implicitly set the return type as void | number.

function divide(a: number, b: number) {
if (b === 0) {
return;
}
return a / b;
}

Instead, I want to ensure a number is returned.

function divide(a: number, b: number): number {
if (b === 0) {
throw new Error("Can't divide by 0");
}
return a / b;
}

While unexpected types like the above are easy to spot in small examples, they can be very subtle in large function bodies.

These rules might look arbitrary: why not add explicit types to variables?

In a way that’s true, but it’s important to maintain balance. We build software that changes over time. And the tighter you fasten the screws, the harder it is to loosen them.