Blog

How many Controllers should you have? [Laravel]

Controllers are the life and blood of a Laravel application. It’s impossible to imagine a framework without them (well, it is, but technically something has to receive the route action, and whether it’s a class or function, it becomes a controller, so to speak).

In the last 3-4 years of my development experience, I went through a minor transformation when it comes to the number of controllers in my application. Earlier, my reasoning was like this: “Controllers, well, control stuff; what they control are the business entities — customers, orders, sellers, etc.”.

So, it was natural to have one “controller” per entity, and the directory structure would look like this:

Controllers
 - UserController.php
 - CustomerController.php
 - SellerController.php
 - [ . . . ] 

Looks very pristine to the eye: all the controllers live inside an aptly-named directory, and all clearly demarcate their territory. Just like the number of figureheads in a system, the fewer the better, right?

The approach worked, but only as far as trivial projects like To-Do List were concerned. In any real-life system, an entity is involved in so many transactions that its controller ends up having a few dozen functions and hundreds of lines of code. Not pretty at all.

I then came across the approach that increases the number of controllers. Now my applications have 20, 30 or more controllers, depending on how many types of transactions every entity is involved in. And they’re into their separate directories. As a result, code organization becomes more sane, and the controllers becomes smaller and more DRY.

Here’s what my new structure looks like:

Controllers
- User
  - UserLoginController
  - UserProfileController
  - UserPurchaseController
- Admin
  - AdminAccountController
  - AdminTransactionController
[. . .]

There’s no limit to how deep you can go, but so far for me, one level deep is good enough.

Agree? Disagree? Do you have a better scheme? I’d love to hear your side. 🙂

The curious relationship between Laravel and Node.js

Even a cursory survey of skills (try LinkedIn) will tell you that a huge percentage of Laravel developers end up learning Node.js. The skills list goes something like this: “LAMP, Laravel, Ionic, Node, Full Stack Developer”. And it’s not just beginners bragging about their skill-set, mind you; I’ve met serious architects who passionately love Laravel and use Node.js.

Why? I can think of a few reasons:

  • The Socket.io library has disgustingly good support for web sockets. When it comes to stuff like chatting and notifications, PHP has no answers while Node.js shines brighter than a thousand suns.
  • Node.js is JavaScript. Everyone learns JavaScript for the browser, and the transition to Node.js becomes easy.
  • It allows you to sprinkle words like “real-time”, “scalable” on to your profile.

Interestingly, you won’t see this skill combination with other, “lesser” PHP frameworks. CodeIgniter, CakePHP, or even WordPress, these developers tag themselves as “LAMP” and get it over with. They are bounded by the four walls of shared hosting, cPanel, GoDaddy and FileZilla, and they’re pretty happy in their wonderland. Node.js? What is that, a new plugin?

Even more interestingly, pure Node.js never give a shit about learning PHP. In fact, they adamantly stick to Node.js. Developers from other languages like Go, Elixir, Java, Scala, etc., never learn PHP. They also don’t learn Node.js. Why? Probably because their language ecosystems already have great support for web sockets and soft real-time communication (I hear the Netty server kicks some serious ass, and Elixir . . . well, that’s on a whole new level).

But more importantly, why do Laravel developers don’t get attracted to other alternatives? Why don’t Laravel developers get tired of the fact that Node is a disaster on multi-core CPUs? Or that it has hideous memory leak problems? Or that npm run build alone takes 1.6 GB of peak RAM? Or that the npm ecosystem is eccentric, to say the least? Or that Golang is much smaller, neater, easier to learn, and absolutely rock-solid?

We can never know the real reason, but I’ll attribute it to laziness. The bulk of PHP developers are not passionate (just dive into the Ruby and Python communities and you’ll know what I mean). Laravel has turned a bland language into something more enjoyable, but that’s about as far as the average developer is willing to explore. The more serious ones end up embracing Symfony, or go the framework-less way, but the other ones remain stuck with the language they know. Why make the massive effort of learning something new? Why not just rinse and repeat?

Any developer who learns these other languages seriously will drop PHP like a rotten banana. I say that as a PHP developer myself. Maybe I’m lazy, too?

Rust Tutorial – Part 6 – Functions

Functions in Rust are much like functions in conventional languages – simple entities that accept an input and produce an output (but not always). Here’s a very simple example of a function in Rust:

fn main() {
    simple_function(32);
}

fn simple_function(x: i8) {
    println!("The value received was {}", x);
}

So, we see that functions are defined using the keyword fn. You might have noticed that main() is also a function defined with fn. The value 32 is passed to the function, and it gets printed to the console. The only catch here is the type of the variable: Rust needs to know in advance the type of value that’ll be arriving in the function. I chose i8 because our example carries a really small integer. Generally, you’d want to use i32 unless memory is at a premium.

But what if we want our function to return a value? It can, as long as we tell Rust in advance what the return value’s type will be. Let’s see another example:

fn main() {
    let x = simple_function(10);
    println!("Got {} from function", x);
}

fn simple_function(x: i8) -> i8 {
    return x * 2;
}

The output, unsurprisingly, is Got 20 from function. We need to be careful when defining functions. If the outcoming value is larger than what the declared type can hold, things will blow up:

fn main() {
    let x = simple_function(10);
    println!("Got {} from function", x);
}

fn simple_function(x: i8) -> i8 {
    return x * 20000;
}

Now are multiplying x by 20000, and there’s no way the result can be contained in an 8-bit integer (i8). Let’s see what we get when we compile it:

warning: literal out of range for i8
  --> 01_variables_and_mutation.rs:14:16
   |
14 |     return x * 2000000;
   |                ^^^^^^^
   |
   = note: #[warn(overflowing_literals)] on by default

We’ve been warned; there’s going to be integer overflow. If we go ahead and run the program anyway, the sky falls down:

thread 'main' panicked at 'attempt to multiply with overflow', 01_variables_and_mutation.rs:14:12
note: Run with `RUST_BACKTRACE=1` for a backtrace.

There’s another trickery related to returning values, instead of saying return x * 2;, you can simply write x * 2 (note, no semi-colon):

fn simple_function(x: i8) -> i8 {
    x * 2
}

This works as intended. Why? Well, the details are a bit technical, but basically it’s the different between statements and expressions in a programming language. Statements do things, expressions return values. But the catch is that what’s expression in one programming language isn’t in another. So, something like this doesn’t work in Rust:

let y = (let x = 6);

This is an error, because let x = 6; doesn’t return a value (this will come as a major surprise to folks from C, Python, Java, Ruby, etc.). And that is so because x = 6; is considered a statement in Rust. It does something (Assigns 6 to x), but doesn’t return it. without the semi-colon, x * 2 is an expression and returns the value of x plus 2.

Is all this hair-splitting any practical use? Yes, if you ever want the value of one let to be returned to another variable:

fn main() {
    let y = {
        let z = 10;
        z + 2
    };

    println!("y is {}", y);
}

Looks odd, I’ll be honest, but it does what we need. We get y is 12 when we run the program.

A word of caution before we finish: using something like return z + 2; won’t work in the last example as the return statement marks the end of the code. I encourage you to try that and see what happens. 🙂

Rust Tutorial – Part 5 – Tuples and more

Tuples are perhaps the most fun data type we’ll encounter in Rust. They are convenience and elegance rolled into one, as we’ll soon see. The idea behind tuples is to let you group together items of different types. If you’re coming from a language like PHP, you might like to think of associative arrays; the Python equivalent would be the tuple or the list; the C equivalent would be structs; and so on.

Rust tuples are convenient

Here’s how you define a tuple in Rust:

let tup = (500, 6.4, 1);

As you can see, Rust recognizes a tuple from the round brackets. You’ll note that we have two (or three?) different data types here: two integers and one float, grouped into one.

So, how do you access these items? Rust provides a quite neat syntax, using the dot operator and using the index number of the items (remember, indices in computer science begin with zero):

fn main() {
    let tup = (500, 6.4, 1);
    println!("{}, {}", tup.0, tup.1);
}

No prizes for guessing; this prints 500, 6.4.

Rust tuples are elegant

And now, ladies and gentlemen, comes the part we’ve been hyping up so much: elegance. Some will argue that this is more convenience than elegance, but that’s a subjective thing.

You can also access a tuple’s items using something known as pattern matching:

fn main() {
    let tup = (500, 6.4, 1);
    let (x, y, z) = tup;
    println!("{}, {}, {}", x, y, z);
}

Whoa! Let’s step back and admire this masterpiece for a minute. The first line, tup = (500, 6.4, 1); creates the tuple. We’re then “unrolling” or “unpacking” the tuple directly into three variables called x, y and z. In one single stroke, x becomes 500, y becomes 6.4, and z becomes 1, as shown by the output:

500, 6.4, 1

The important thing here is that the types of the variables must also match. Let’s try to be smart and see how it goes:

fn main() {
    let tup = (500, 6.4, 1);
    let (x, y, z): (bool, f32, i16) = tup;
    println!("{}, {}, {}", x, y, z);
}

We’ve defined three mutable variables (because they’ll need to change as soon as they receive values from the decomposed tuple). Of these, x is the unfortunate one: it’s a boolean, but it’s going to be slapped in the face with 500. Rust detects our “cleverness” and cries foul:

error[E0308]: mismatched types
 --> 01_variables_and_mutation.rs:6:17
  |
6 |     (x, y, z) = tup;
  |                 ^^^ expected bool, found integral variable
  |
  = note: expected type `(bool, f32, i16)`
             found type `({integer}, {float}, {integer})`

Look closely: Rust says it expected the order of the receiving types to be (bool, f32, i16) but found ({integer}, {float}, {integer}) in the tuple.

This is just a preview of pattern matching. The concept goes much deeper, and although simple to understand, results in very clean code that is easy to understand. We’ll see more of pattern matching later on in this tutorial.

Other data types

Finally, a quick word on other data types; Rust also has arrays for grouping items of similar type, but there’s one striking difference: arrays have a fixed length! Yes, that alone is enough to make eyes pop out, but Rust has a reason for doing so. If you really need array-like constructs that can grow in size, Rust offers vectors.

But enough for now. We’ll dive into these types when we need to.

[The link to the next tutorial is here.]

Rust Tutorial – Part 4 – Primitive Data Types

[This post is part of the series on Rust programming tutorials that I’m writing for enjoyment. All the tutorial links are here.]

Let’s take it step by step. I assume you know what data types are (if not, please run away; Rust should not be your first programming language – it’s far too interesting and powerful for that), but the term primitive might trip you up.

A quick lookup will tell you that the word ‘primitive’ has associated meaning of ‘old-style’, or ‘related to earlier era’, etc. The idea here is that when programming languages just started, they had little more than integers, characters, and booleans, because that was the only immediate needs the language designers could see. As programming evolved later on, having to think of everything as a separate integer became a chore (imagine having to maintain your daily expenses in separate variables – that’s 365 variables for the year. Yikes!), people started designing and use higher-order (read, more useful and more complex) data structures. You might have heard of structures, objects, arrays, lists, hash maps, tuples, etc.

So Rust has primitives. Or, simpler data types. Just four of them – integers, floats, characters and booleans. And since Rust is a systems programming language, it cares about what the size of these types is. That’s because RAM and CPU are at a premium, and if you’re trying to write something like an operating system, you’d better be damned careful with them.

So Rust has several types of integers – 8 bits, 16 bits, 32 bits, and so on; two types of floating point numbers – 32-bit and 64-bit; and so on. I don’t want to bore you with details here. We’ll look at it in more detail when it matters. But for now, please understand that an integer is not just an integer in Rust. Although the examples so far have written stuff like let x = 42; and left everything to the compiler, this sloppiness won’t do for long.

Data types have sizes, and we need to start taking responsibility for them.

[The link to the next tutorial is here.]

Rust Tutorial – Part 3 – Constants

[This post is part of the series on Rust programming tutorials that I’m writing for enjoyment. All the tutorial links are here.]

Rust allows you to write constants; that is, things that aren’t going to change at all. If you’ve read the previous tutorial on variables, you might be thinking: why constants when all variables are immutable by default? Good question. And just in case you weren’t thinking like that, begin to. It’s one of the best things you can do for your programming career.

The first very important distinction is that constants can exist in global scope. In other words, this means that is you have a fixed value that needs to shared throughout your Rust application (read ‘many files’), plain old variables won’t cut the mustard.

let y = 10;

fn main() {
    println!("y is {}", y);
}

Something like the above fails to compile. Rust complains that it wasn’t expecting a let statement up there. This means that variables must have a block scope (another fancy way of saying that they must live inside curly braces) and cannot be shared among files.

A constant, however, can:

const AGE: u8 = 10;

fn main() {
    println!("Age is {}", AGE);
}

The above works. But did you notice that odd little u8 there? This stands for ‘unsigned 8 bits’, and happens to be the size and type of the constant we are declaring (here’s how it helps; and if you’re totally clueless about integer sizes, I’d suggest reading up some computer architecture . . . something like this).

Anyway, back to the point. If you now have a Rust project with multiple files, the AGE constant will be available to all of them, and will last as long as the program lasts.

Another, less important, distinction is that constants cannot be re-initialized (the following will throw an error):

const AGE: u8 = 10;
const AGE: u8 = 12;

fn main() {
    println!("Age is {}", AGE);
}

While variables can be:

fn main() {
    let x = 12;
    println!("x is {}", x);    
    let x = 23;
    println!("x is {}", x);
}

A curious aside, by the way. Rust compiler will warn you bitterly if you create variables you won’t use. I originally wrote the following program for the previous code:

fn main() {
    let x = 12; 
    let x = 23;
    println!("x is {}", x);
}

But when I compiled it, Rust said:

core$ rustc 01_variables_and_mutation.rs 
warning: unused variable: `x`
 --> 01_variables_and_mutation.rs:2:9
  |
2 |     let x = 12;
  |         ^
  |
  = note: #[warn(unused_variables)] on by default
  = note: to avoid this warning, consider using `_x` instead

Kinda neat, right?

At this point, I have a question nagging me, which I’m going to post on Rust forums: If the compiler can figure out the type of the variable from a let statement, why can’t it do so from a const statement? Why are we required to specify the type and size of storage when declaring a constant?

(Update: Shortly after, I did take this discussion to the Rust forums.)

[The link to the next post is here.]

Rust Tutorial – Part 2 – Variables

[This post is part of the series on Rust programming tutorials that I’m writing for enjoyment. All the tutorial links are here.]

Variables . . . things that hold other things. What other things? These other things vary from language to language, and range from values to references to direct memory addresses (the last one being very, very scary, and is the reason I did no system programming so far but have now picked up Rust).

Variables, as the term implies, are supposed to vary, or change over the course of the program. So without wasting any more time, let’s try out variables in Rust:

fn main() {
    let x = 32;  
    println!("The value of x is {}", x);
}

And when you run it:

The value of x is 32

Well, no surprises there! You’ll notice that the curly braces{} are used to substitute variable values in a string we’re about to print. That’s how Rust knows where to fit what when the final output is shown.

Now let’s try some more simple stuff:

fn main() {
    let x = 32;
    x += 23;
    println!("The value of x is {}", x);
}

And when you compile it, you get:

error[E0384]: re-assignment of immutable variable `x`
 --> 01_variables_and_mutation.rs:3:5
  |
2 |     let x = 32;
  |         - first assignment to `x`
3 |     x += 23;
  |     ^^^^^^^ re-assignment of immutable variable

error: aborting due to previous error

Uh, oh. An error? Surely we’ve hit upon a bug in the compiler? What could be more simple than adding an integer value to a variable that already contains an integer?

Well, while this sounds conceptually valid, for Rust, not all variables are created equal. Some can change over the course of time, and some cannot. By default variables can’t be changed once they’ve been set; if you want them to change, you need to explicitly tell the compiler so:

fn main() {
    let mut x = 32;
    x += 23;
    println!("The value of x is {}", x);
}

Notice the keyword mut here. It tells Rust that this variable is mutable. In other words, we intend its value to change over time. And if you compile and run this program now:

The value of x is 55

All fine and dandy!

But we’ve left out any important point: why, in the name of God, can variables not be changed in Rust by default?

Well, I’m afraid the complete explanation is really, really long, but I’ll try to do my best.

Basically, when the world started programming, the popular languages in the world were those that followed the Object Oriented approach to modeling solutions. Entities in our programs were thought of as representing something independent and concrete, and a large body of theory was developed to “simplify” the process. Languages like C (though not object-oriented), C++ and Java became incredibly popular, which was followed by JavaScript, PHP, Python, Ruby, and so forth.

After so many years of programming like this, people started to feel that they were spending too much time pulling their hair trying to track changes made to their variables. When something is accessible by a lot of things and can be changed, it’s not pretty. And so began a gradual shift to another style of programming called Functional Programming, where everything is a function and there is not much theory to digest. Functional Programming style insists on immutability – things cannot be changed. You only send something to a function, which works on it and returns a new, transformed value, and then you use that new value. The argument is that this approach is simpler to program, track and teach, and results in fewer bugs. The surging popularity of languages like Clojure, Scala (though not purely functional), Elixir, Haskell, F#, etc., seems to indicate that (hey, Rust is also functional! 🙂 ).

There seems to be a homecoming of sorts in the programming world, as people are re-discovering the joys of one of the oldest forms of programming (warning: very heavy read).

So, to avoid confusion and keep bugs to a minimum, Rust won’t allow you to change a variable’s value by default.

Speaking of immutability, the Erlang language (on which WhatsApp’s inital backend was built) doesn’t allow you to ever change a variable value, and its proponents say it’s the best thing they saw in their lives.

Man, that got long despite my best efforts. 😐

But I hope it was of some help and interest.

The next part of this tutorial is here.

Rust Tutorial – Part 1 – Hello World

[This post is part of the series on Rust programming tutorials that I’m writing for enjoyment. All the tutorial links are here.]

Every programming language must begin with printing “Hello, world!” to the screen. It’s not mandatory, but it’s a tradition honored by great programmers through the ages; and who am I to break that tradition?!

So, having installed Rust on your machine, let’s move on to writing our very first Rust program. Create a directory where you’ll be storing the Rust files (here’s how I organize code used for learning); let’s call this directory `rusty-learning`. Inside this directory, we’re going to create a new file to start our journey. Use your favorite text editor (ed, nano, vim, emacs, Sublime, Notepad++, Comodo, Spyder, whatever . . .) and create a new file called 01_hello_world.rs. The rs extension hints that it’s a Rust source file. (Why add the unnecessary 01 at the beginning? It’s part of the scheme I follow, and is explained in the article linked above.)

Let’s add the following code to this file:

fn main() {
    println!("Hello, world!");
}

(I’m sorry for the plain-vanilla look. I couldn’t find a WordPress plugin that supports Rust syntax highlighting out of the box. I’ll keep looking, though.)

We’ll get to the explanation in a minute; for now, let’s run the code and see what happens:

$ rustc 01_hello_world.rs

The rustc command invokes the Rust compiler (much like the gcc command if you’ve done any C programming) and asks it to compile the file 01_hello_world.rs to a binary executable file. If all goes well (hopefully there are no typos), you’ll see . . . nothing.

Yes, that’s right. If the command prompt quietly returns, it means Rust was able to compile your file successfully. How can you be sure? Simply list all the files in the directory and you’ll see this:

$ ls .
01_hello_world.rs 01_hello_world

Look again. There’s a second file now: named 01_hello_world, and it has no extension. That’s because it’s a binary file and can be run straightaway:

$ ./01_hello_world
Hello, World!

Three cheers! We’ve just run our first Rust program successfully!

I admit the output isn’t very spectacular, but hey, the journey of a thousand miles — okay, okay, don’t hit me. I know you don’t like decrepit quotes. 🙂

On to how the program works.

I believe that for experienced programmers, the program is a cakewalk. But just in case you’re from a scripting language background, here’s some introduction.

In compiled languages, there has to be an entry point for the compiler, from where it starts understanding your code, linking it and converting it into one big executable. Conventionally, this entry point has been a function called main, which is what we see here. Without main, the compiler will think that you’re trying to create a library file (a set of reusable code files) and will not produce an executable.

So, once the compiler sees main()it knows it’s time to start building the program. It then encounters the next line, which calls the println marco (notice the ‘!’ at the end of the function name? That shows it’s a macro). Macros are different from functions, and are part of an advanced topic called Metaprogramming. Although we’ll cover Metaprogramming much later, for now it’s enough to understand that macros allow us to get underneath the skin of the language and do things that its syntax wouldn’t normally allow.

So, the println! macro sends the given string to the standard output, which happens to be your terminal in this case. As a result, you see “Hello, World!” printed.

I hope you enjoyed this tutorial. If you have any comments or rants, feel free to vent out below. 🙂

Go to next tutorial.

How I organize code when I’m learning

So here’s what this looks like from the rooftop:

You’ll see lots and lots of directories there, which reflects my impulsive nature. There’s stuff like NodeJS there (which I left half-way), zeromq (which I never even got started on), Go (which I did finish, by the way!), and more.

But that’s not all.

The real point is that inside this shallow hierarchy, I maintain a hierarchy that reflects my learning progress. At the same time, I make sure to write copious comments.

Here’s what I mean. I currently happen to be learning Design Patterns in PHP, and here’s what that directory looks like:

Notice that the directories have been numbered as well. That’s because that’s the order in which the design patterns appear in the book. It helps because these concepts build upon the previous one usually, and so are naturally aligned for easy revision.

And here’s how I typically comment:

<?php require_once 'ElectronicNotifierFactory.php'; /** * Unlike the Simple Factory pattern, notice that we are no more relying * on a single class, but calling different classes that we know follow * the same interface. The advantage is that this way, we can keep adding * more factories without having to modify the original class. That's a * BIG advantage as far as the Open/Closed principle is concerned. Note that * if we were to do this via the Simple Factory pattern, we would end up * having to modify the original class, and then we'd have the problem of * having to communicate the extra possibility to all the clients using * that library. */ $mobile = ElectronicNotifierFactory::getNotifier("SMS", "07111111111"); echo $mobile->sendNotification() . PHP_EOL;
$email = ElectronicNotifierFactory::getNotifier("Email", "test@example.com");
echo $email->sendNotification() . PHP_EOL;

/**
* And here's an example use case -- adding another type of notifier
*/

require_once 'CourierNotifierFactory.php';
$post = CourierNotifierFactory::getNotifier("Post", "13 Friday Street, SF1S 3ZZ");
echo $post->sendNotification() . PHP_EOL;

/**
* While the textbooks tout this pattern for upholding the sanctity of the
* Open/Closed principle, they don't say what would happen if we wanted to
* add a new type of electronic notifier, say, Socket notifications. Could
* this be symptomatic of the underlying problem that has causing a gradual
* shift from Object Oriented programming?
*/

You’ll note that the comments include my learning from the book, as well as my doubts and apprehensions. This helps me a lot the next time I want to go through Design Patterns quickly. All my learning is frozen in time, and if I have answered these questions by then, I simply remove the comments and move on. All in all, it’s a working mini-book in itself that other people can read from and save time. 🙂

And oh, just in case you were wondering, the Design Patterns code is available on my GitHub.

Simple, lightweight Rust tutorials

So I finally decided to write some tutorials. For Rust. I’ve kept myself from writing any tutorials before, but this time I made an exception. Here’s why.

Be advised, though. There’s nothing special in these tutorials. I write them as I learn Rust from the only excellent book online, and the content and structure of the tutorials mimics that of the book.

I write them for my own pleasure, primarily. I have, however, added copious comments and side-commentary. As such, I believe these tutorials will be on immense value to any junior developer who’s been blinkers-on so far, but now wants to enjoy programming and dive a little more into the systems he programs daily.

Here’s a list of my Rust tutorials: