Python “Magic” Methods: Part 1

Java was the first language I used professionally and is the scale by which I measure other languages I learned afterward. It's an OOP statically-typed language. Hence, Python feels a bit weird because of its dynamic typing approach.

For example, Object offers methods equals(), hashCode(), and toString(). Because all other classes inherit from Object, directly or indirectly, all objects have these methods by definition.

Resizing Images On-The-Fly

As a web architect, one of the many issues is asset management. And the most significant issue in assets is images. A naive approach would be to set an image and let the browser resize the image via CSS:

CSS
 
img {
    height: 100%;
    width: 100%;
    object-fit: contain;
}


Monkey-Patching in Java

The JVM is an excellent platform for monkey-patching.

Monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. A monkey patch (also spelled monkey-patch, MonkeyPatch) is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.) without altering the original source code.

Send Your Logs to Loki

One of my current talks focuses on Observability in general and Distributed Tracing in particular, with an OpenTelemetry implementation. In the demo, I show how you can see the traces of a simple distributed system consisting of the Apache APISIX API Gateway, a Kotlin app with Spring Boot, a Python app with Flask, and a Rust app with Axum.

Earlier this year, I spoke and attended the Observability room at FOSDEM. One of the talks demoed the Grafana stack: Mimir for metrics, Tempo for traces, and Loki for logs. I was pleasantly surprised how one could move from one to the other. Thus, I wanted to achieve the same in my demo but via OpenTelemetry to avoid coupling to the Grafana stack.

Introduction to the Tower Library

One of the components of my OpenTelemetry demo is a Rust application built with the Axum web framework. In its description, axum mentions:

axum doesn't have its own middleware system but instead uses tower::Service. This means axum gets timeouts, tracing, compression, authorization, and more, for free. It also enables you to share middleware with applications written using hyper or tonic.

Ops-Friendly Apache APISIX

Though I always worked on the Dev side of IT, I was also interested in the Ops side. I even had a short experience being a WebSphere admin: I used it several times, helping Ops deal with the Admin console while being a developer.

Providing a single package that Ops can configure and deploy in different environments is very important. As a JVM developer, I've been happy using Spring Boot and its wealth of configuration options: command-line parameters, JVM parameters, files, profiles, environment variables, etc.

My Final Take On Gradle (vs Maven)

I tweet technical content that I consider interesting, but the funny tweets are the ones that get the most engagement. I attended the JavaLand conference in March, stumbled upon the Gradle booth, and found this gem:

Of course, at some point, a fanboy hijacked the thread and claimed the so-called superiority of Gradle. In this post, I'd like to shed some light on my stance, so I can direct people to it instead of debunking the same "reasoning" repeatedly.

System Architecture: Move Authentication to the API Gateway

When exposing an application to the outside world, consider a Reverse-Proxy or an API Gateway to protect it from attacks. Rate limiting comes to mind first, but it shouldn't stop there. We can factor many features in the API Gateway and should be bold in moving them from our apps. In this post, I'll show how to implement authentication at the Gateway API stage.

Overall Authentication Flow

The API Gateway doesn't authenticate but delegates authentication to an authentication provider. After authentication, the Gateway forwards the request to the app. The app checks authentication and gets the associated identity and permissions.

Apache APISIX Without etcd

etcd is an excellent key-value distributed database used internally by Kubernetes and managed by the CNCF. It's a great option, and that's the reason why Apache APISIX uses it too. Yet, it's not devoid of issues.

First, some mention scalability, but one can expect this from a distributed data store that values consistency. Another issue may be the need for more familiarity with etcd. It's relatively new, so your Ops team may need help operating it correctly while having decades of operating MySQL or Postgres. Finally, only a few etcd users are aware that it lacks maintainers:

Reactive Database Access on the JVM

A couple of years ago, Reactive Programming was all the rage, but it had one big issue: reactive stopped as soon as you access a SQL database. You had a nice reactive chain up to the database, defeating the whole purpose. Given the prevalence of SQL databases in existing and new apps, one couldn't enjoy the full benefits of Reactive Programming but still pay the full price of complexity.

Since then, the landscape has changed tremendously. Most importantly, it offers many reactive drivers over popular databases: PostgreSQL, MariaDB and MySQL, Microsoft SQL Server, Oracle, you name it! Even better, some frameworks provide a reactive API over them.

Sticky Sessions With Apache APISIX — The Demo

Last week, we described the concept behind sticky sessions: you forward a request to the same upstream because there's context data associated with the session on that node. However, if necessary, you should replicate the data to other upstreams because this one might go down. In this post, we are going to illustrate it with a demo.

The Overall Design

Design options are limitless. I'll keep myself to a familiar stack, the JVM. Also, as mentioned in the previous post, one should only implement sticky sessions with session replication. The final design consists of two components: an Apache APISIX instance with sticky sessions configured and two JVM nodes running the same application with session replication.

Sticky Sessions With Apache APISIX

Sticky sessions, also known as session affinity, is a mechanism by which a routing component that acts as a facade always routes a request to the same underlying upstream node. In this post, I'll describe the reason behind sticky sessions, available alternatives, and how to implement them via Apache APISIX.

Why Sticky Sessions?

Sticky sessions became popular when we stored the state on the upstream node, not the database. I'll use the example of a simplified e-commerce shop to explain further.

Evaluating Apache APISIX vs. Spring Cloud Gateway

Given the number of API Gateways available on the market, I'm regularly asked which is better. Better is a very subjective term. However, there's no denying that if you're advocating for a product, you should know your product and its competitors. In this post, I'd like to share my understanding of Spring Cloud Gateway and how it compares to Apache APISIX.

I'm cautious when comparing products because most comparisons I read are heavily biased. That's a risk, especially when working on one of the products one is comparing. I'll also avoid "benchmarketing" - when you benchmark products in a context that favors your own; I'll focus on the so-called Developer Experience.

GitLab Pages Preview

When I write Apache APISIX-related blog posts, I want my colleagues to review them first. However, it's my blog, and since I mix personal and business posts, I want to keep them from the repository. I need a preview accessible only to a few, something like Vercel's preview. I'm using GitLab Pages, and there's no such out-of-the-box feature.

I tried two methods: GitHub gists and PDFs. Both have issues.

Health Check Response Format for HTTP APIs

I'm continuing my journey of getting more familiar with HTTP APIs by reading related RFCs. This time, I read the Health Check Response Format for HTTP APIs at the suggestion of Stefano Fago. In this post, I'd like to summarize my reading.

Note that it's a draft. Moreover, it has been dormant for nearly two years and, thus, has been automatically expired. However, it's the closest to a specification on health checks and thus deserves some love.

Managing Data Residency, the Demo

I explained the concepts and theory behind Data Residency in a previous post. It's time to get our hands dirty and implement it in a simple demo.

The Sample Architecture

In the last section of the previous post, I proposed a sample architecture where location-based routing happened at two different stages:

Working on an Unfamiliar Codebase

In our profession, it's common to work on an unfamiliar codebase. It happens every time one joins a new project or even needs to work on a previously untouched part in big ones. This occurrence is not limited to a developer having to fix a bug; it can be a solution architect having to design a new feature or an OpenSource contributor working on a GitHub issue in their free time. Hence, I want to describe how I approach the situation so it can benefit others.

An Example Issue

To illustrate my point, I'll use a common GitHub issue requesting a new feature on an Open Source project.