For a modern startup, choosing the technologies to use is often one of the biggest decisions to make. For a technical startup, the technical stack, or “tech stack”, plays an even more crucial role in the success of the company. Not only does it determine the product quality, but it also affects the maintainability and extendability of the product and the day-to-day developer experience. At the same time, the recruitment market (the "talent pool") is no less important—at the end of the day; a tech stack is only as good as the people who work with it.

As a technology startup whose flagship product is a web platform, we don't make technical decisions lightly. The programming languages we choose to build the applications, the frameworks to power them, the database systems to store their millions if not billions of records or the platforms to host and serve them—each and every one of these decisions are made with careful considerations for the points above.

This article is the first of a series about what technologies we use at eve underneath the user interface, the reasons we think they're the most suitable for us and sometimes even the arguments against them.

Part 1: The API Stack

eve's platform is backed by an API that is built on top of Laravel, the highly popular PHP framework, and follows the OpenAPI specification. At the time of this writing, our Laravel version is 8.19.0, and our PHP version is 7.4, which are both relatively modern—in fact, 8.19.0 is the latest Laravel version, when 7.4 is the latest PHP version that's compatible with all the packages we depend on, and the just-released PHP 8 is already on our roadmap.

➜  api php artisan --version
Laravel Framework 8.19.0

➜  api php --version
PHP 7.4.11 (cli) (built: Oct  6 2020 10:35:51) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.11, Copyright (c), by Zend Technologies

The Case for PHP

PHP is not exactly new. Having first appeared in 1995, almost 26 years ago, it has been through its ups and downs. Serving WordPress, Facebook, Wikipedia, as well as a bunch of other big names in tech, PHP has consistently been listed among the most popular, if not the most popular, server-side programming language and is responsible for a whopping estimation of over 80% of known sites on the internet.

Now, PHP isn't without its flaws—developers frown upon how easy it is to write spaghetti PHP code and the questionable language decisions, its early (non-existent) type system and its operator madness, its inconsistent function names and order of arguments (strtoupper and bin2hex anyone?) and the indecipherable error codes and whatnot. While some of these problems still persist due to backward-compatibility reasons, PHP nowadays is just as modern as the next shiny programming language. Take a look at this (totally arbitrary) code:

use App\Cache\AbstractCacheManager;
use App\Cache\CacheManagerInterface;
use App\Cache\Traits\InteractsWithStorage;

#[AutoConfigured, Autowired]
class SimpleCacheManager extends AbstractCacheManager implements CacheManagerInterface
{
    use InteractsWithStorage;

    private WeakMap $cache;

    public function __construct(private string $identifier) {}
 
    public function getCache(int|string $key): object
    {
        return $this->cache[$obj] ??= $this->getRecordFromStorage(id: $key);
    }
}

In only a couple of lines of code, we've managed to showcase:

  • Feature-complete object-oriented inheritance with abstractions and interfaces
  • Code composition/reuse with traits
  • Attributes
  • WeakMap
  • Property promotion
  • Named arguments
  • Union types
  • Null-safe operators

Pretty decent for a 26-year old programming language if you ask us, and PHP is adding more features, becoming more performant and using fewer resources as we speak. Throw in the new JIT (just-in-time compilation), the famous ease of deployment, the mature ecosystem and the vast talent pool and things will keep getting better.

The Case for Laravel

Created by Taylor Otwell in 2011 as a more advanced alternative to CodeIgniter, Laravel quickly rose to become the most popular PHP framework in the world, widely adopted by millions of developers and—some would say—helped redefine the PHP landscape.

It's safe to say Laravel is to PHP like PHP is to programming languages as a whole. Among others, Laravel shines with its beautiful syntax, its fluent object-relational mapper (ORM)—Eloquent—and its convenient usage of facades. These very features, however, are also what draw criticism on the framework; some people find them to be too magical, hard to reason with, and sometimes even in violation of several software design principles.

As seasoned developers with broad experience in multiple languages and frameworks, we at eve pride ourselves on being able to make use of Laravel's best offerings and at the same time knowledgeable enough to avoid its shortcomings or common pitfalls. Take a look at our actual code that handles updating an event:

public function update(Event $event, UpdateEventRequest $request)
{
    $this->authorize('manage', $event->company);

    $attributes = $request->validated();
    $logo = array_pull($attributes, 'logo');

    if ($logo) {
        $attributes['logo'] = $this->logoService->processLogo($logo);
    }

    $this->eventService->updateEvent($event, $attributes);

    return EventResource::make($event);
}

This controller method consists of only 15 lines of code (4 of them are blank lines), yet is 100% functional. Here, we're making use of:

  • Model binding
  • Eloquent API resources
  • Authorization with policies
  • Form request validation
  • Array helpers

All of these are mixed with the consistent use of the dependency injection pattern that allows for testability, readability and reasonability. There's no usage of magical static facade calls or direct dependencies on models. On top of that, we run frequent static analysis with PHPStan and make coding standards a fail-fast step in our build pipeline. Needless to say, we're pretty happy with what we've got so far.

A Word or Two on OpenAPI Specification

Formerly called Swagger Specification, OpenAPI Specification is a description format for REST APIs. An OpenAPI file basically lets you describe your entire API, including its endpoints and operations, the expected input and output for each operation and the authentication methods, among other things. Strictly following OpenAPI Specification from day one has allowed our backend and frontend developers to communicate with each other using the same "language" and has saved us a great deal of time going back and forth. Frontend developers don't even need to wait for the API to be completed to start implementing a feature—they can simply create a mock with the agreed specifications and work with that instead.

Tools like Stoplight Studio and Swagger UI take this one step even further by providing us with a user-friendly visual editor, making the API design process a breeze.

eve%20-%20Underneath%20the%20UI%20f8cf67e8a9cc4d7784bce82bfbf9a91e/Untitled.png
Screenshot of Stoplight Studio showing the specifications for our /age-ratings API endpoint.

Wrapping Up

Some startups develop a mentality of "move fast and break things." Being a young startup ourselves, we at eve are extremely open to experiments. When it comes to the technical foundation of our organization though, we have the tendency to lean toward battle-tested technologies and solutions with a rich ecosystem and vibrant community instead. The result? Our team of four managed to deliver the first version of our product in a very short amount of time (a couple of months!) while still adhering to the best principles, patterns and practices and maintaining a very high-quality codebase.