API PostgreSQL PostgREST API Gateway Apache APISIX no code MVP

A poor man's API

Creating a full-fledged API requires resources, both time and money. You need to think about the model, the design, the REST principles, etc., without writing a single line of code. Most of the time, you don’t know whether it’s worth it: you’d like to offer a Minimum Viable Product and iterate from there. I want to show how you can achieve it without writing a single line of code. The solution The main requirement of the solution is to use the PostgreSQL database. It’s

API Web API RFC

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

API lifecycle management REST

Evolving your RESTful APIs, a step-by-step approach

Designing an intuitive, user-friendly RESTful API is a tough job. It might already be a massive task if it’s your first attempt. Planning for the lifecycle management of your API is likely to be an afterthought. But it’s possible anyway: in this post, I’d like to propose a no-nonsense approach to evolving your APIs, even if it was not planned. The initial situation Let’s consider a sample application that says 'Hello' when using it. > curl http://org.apisix/hello Hello world > curl

system logger logging API facade abstraction

System Logger

December was not a good time for Java developers and even less for Ops. The former had to repackage their apps with a fixed Log4J’s version, and the latter had to redeploy them - several times. Yet, every cloud has a silver lining. In my case, I learned about System.Logger. A good time to start using the new standard System.Logger API introduced in Java 9: https://t.co/SaBUnqEZqF. It works like SLF4J and by default logs using JUL but can use Log4J or any othet logging under the hood. http

extension API

Extending third-party APIs in different languages

The need for shorter and shorter Time-To-Market requires to integrate more and more third-party libraries. There’s no time for the NIH syndrom anymore if it ever was. While most of the time, the library’s API is ready to use, it happens that one needs to 'adapt' it to the codebase sometimes. How easy the adaptation is depends a lot on the language. For example, in the JVM, there are a couple of Reactive-Programming libraries: RxJava, Project Reactor, Mutiny, and coroutines. You migh

hack API

Hacking third-party APIs on the JVM

The JVM ecosystem is mature and offers plenty of libraries, so you don’t need to reinvent the wheel. Basic - and not so basic - functionalities are just a dependency away. Sometimes, however, the dependency and your use-case are slightly misaligned. The correct way to fix this would be to create a Pull Request. But your deadline is tomorrow: you need to make it work now! It’s time to hack the provided API. In this post, we are going through some alternatives that allow you to make

Stream Collector API

Teeing, a hidden gem in the Java API

Last week, I described a use-case for a custom Stream Collector. I received a intriguing comment on Twitter: Interesting article. For completness' sake this specific problem could also be solved using the standard teeing collector— Miguel Martins (@Miguucm) May 3, 2021 Hats off to you, Miguel! Your comment revealed a method I didn’t know! So I decided to investigate what the teeing() method is about. Returns a Collector that is a composite of two downstream collectors.

Stream Collector API

A real-world example of a Stream Collector

Java Stream’s Collectors methods fit most use-cases. They allow returning either a Collection or a scalar. For the former, you use one of the toXXX() method, for the latter, one of the reducing() one. Let’s imagine an e-commerce platform that implements a shopping cart. The cart is modeled as the following: This diagram might translate into the following (abridged) code: Product.java public class Product { private final Long id; (1) priva

Functional Programming API Optional Stream

Optional.stream()

This week, I learned about a nifty 'new' feature of Optional that I want to share in this post. It’s available since Java 9, so its novelty is relative. Let’s start with the following sequence to compute the total price of an order: public BigDecimal getOrderPrice(Long orderId) { List<OrderLine> lines = orderRepository.findByOrderId(orderId); BigDecimal price = BigDecimal.ZERO; (1) for (OrderLine line : lines) { price = price.add(line.getPrice());

bug API

A sorting bug

Lately, I succumbed to nostalgia, and agreed to do some consulting for a customer. The job was to audit the internal quality of an application, and finally to make recommandations to improve the code base and reimburse the technical debt. While parsing the source code, I couldn’t help but notice a bug in the implementation of a Comparator. This post is to understand how sorting works in Java, what is a Comparator, and how to prevent fellow developers to fall into the same trap. Even if it

API

Map merge and compute, hidden API diamonds

If you’ve been working in Java since 'quite some time', you probably are experienced in using Map objects. One very frequent use-case is to check if a Map contains a value: Get the valueIf the value is null, put an initial value.If isn’t, transform the get value and put the new value into the map under the same key Map<String, Integer> map = new HashMap<>(); // ... Integer value = map.get(key); if (value == null) { map.put(key, 1); } else { map.put(key, ++valu

deduplication API

Deduplication trick in legacy code

It might happen that you need to deduplicate a list of items…​ coming from legacy code. The class - let’s call it LegacyObject has already implementations for equals() and hashCode(). It’s not possible to change the implementation, for fear of breaking the running code. And unfortunately, the Java API doesn’t offer a distinctBy() feature. In that case, a cheap trick is to create a wrapper class around LegacyObject, with the desired implementation: public class L

API JDK design Cloneable

Cloneable, a Java design gotcha

Some time ago, I described a couple of surprising design choices in the JDK functional interfaces API. Lately, during a lesson, a student of mine proposed to shallow-copy an ArrayList by using the clone() method: I thought this is another API gotcha worth writing about. Cloning an object means a new object is created with the same state as the original one. As per the JavaDoc: Creates and returns a copy of this object. The precise meaning of 'copy' may depend on the class of the object.

design API extension function

Extension functions for more consistent APIs

Kotlin’s extension functions are a great way to add behavior to a type sitting outside one’s control - the JDK or a third-party library. For example, the JDK’s String class offers the toLowerCase() and toUpperCase() methods but nothing to capitalize the string. In Kotlin, this can be helped by adding the desired behavior to the String class through an extension function: fun String.capitalize() = when { length < 2 -> toUpperCase() else -> Character.toUpperC