Structured error messages for HTTP APIs

Ever since I started to work on the Apache APISIX project, I’ve been trying to improve my knowledge and understanding of REST RESTful HTTP APIs. For this, I’m reading and watching the following sources: Books. At the moment, I’m finishing API Design Patterns. Expect a review soon.YouTube. I’d recommend ErikWilde' channel. While some videos are better than others, they all focus on APIs.IETF RFCs. Most RFCs are not about APIs, but a friendly person compiled a list of the o

engineering solution engineering

Discuss the problem, not the solution

As a tech guy, I love to discuss technologies. And as discussions go, it’s generally the comparison kind: JVM vs. Net, Java vs. Kotlin, Go vs. Rust, Maven vs. the unspeakable one, etc. However, it’s too easy to fall into the quagmire of the merits and flaws of our beloved toys, talk about them for hours, and not reach a satisfactory agreement. A couple of years ago, I worked as a 'Solution Architect'. The job has different titles, e.g., Solution Designer, Solution Engineer, but the

exceptions lambdas Streams Apache Commons Vavr Functional Programming

Exceptions in lambdas

Java introduced the concept of checked exceptions. The idea of forcing developers to manage exceptions was revolutionary compared to the earlier approaches. Nowadays, Java remains the only widespread language to offer checked exceptions. For example, every exception in Kotlin is unchecked. Even in Java, new features are at odds with checked exceptions: the signature of Java’s built-in functional interfaces doesn’t use exceptions. It leads to cumbersome code when one integrates leg

Rust testing dependency injection

Different test scopes in Rust

I’m still working on learning Rust. Beyond syntax, learning a language requires familiarizing oneself with its idioms and ecosystem. I’m at a point where I want to explore testing in Rust. The initial problem We have used Dependency Injection a lot - for ages on the JVM. Even if you’re not using a framework, Dependency Injection helps decouple components. Here’s a basic example: class Car(private val engine: Engine) { fun start() { engine.start() }

Rust WebAssembly API Gateway Apache APISIX

Rewriting the Apache APISIX response-rewrite plugin in Rust

Last week, I described the basics on how to develop and deploy a Rust plugin for Apache APISIX. The plugin just logged a message when it received the request. Today, I want to leverage what we learned to create something more valuable: write part of the response-rewrite plugin with Rust. Adding a hard-coded header Let’s start small and add a hard-coded response header. Last week, we used the on_http_request_headers() function. The proxy_wasm specification defines several function hooks

Rust WebAssembly API Gateway Apache APISIX

Apache APISIX loves Rust! (and me too)

Apache APISIX is built upon the shoulders of two giants: NGINX, a widespread Open Source reverse-proxyOpenResty, a platform that allows scripting NGINX with the Lua programming language via LuaJIT This approach allows APISIX to provide out-of-the-box Lua plugins that should fit most business requirements. But it always comes a time when generic plugins don’t fit your requirements. In this case, you can write your own Lua plugin. However, if Lua is not part of your tech stack, diving int

DevOps Kubernetes

Introduction to Kubernetes extensibility

Kubernetes offers a lot of benefits: an enormous ecosystem with plenty of actors, self-healing capabilities, etc. There’s no free lunch, though. It also comes with downsides, chief among them its complexity and operating costs. However, the more I work with Kubernetes, the more I think its most significant asset is extensibility. If you need something that the platform doesn’t provide by default, there’s an option to develop it yourself and integrate it. In this post, I’

python depepdency management pip

The maze of Python dependency management

For over 20 years, I’ve developed code for the JVM, first in Java, then in Kotlin. However, the JVM is not a silver bullet, e.g., in scripts: Virtual machines incur additional memory requirementsIn many cases, the script doesn’t run long enough to gain any benefit performance-wise. The bytecode is interpreted and never compiles to native code. For these reasons, I now write my scripts in Python. One of them collects social media metrics from different sources and stores them in BigQ

Kubernetes Gateway API Apache APISIX

A quick glance at the Kubernetes Gateway API

In one of my recent blog posts, I described several ways to access Kubernetes pods. One can access a pod through its IP, but pods are naturally transient. The nominal way is to configure a Service: its IP is stable, and Kubernetes' job is to keep the mapping between a Service and its underlying pods up-to-date. Different kinds of services are available: internal only, NodePort to finally allow access from outside the cluster, and LoadBalancer that relies on a third-party component - in general, a