HTTP Fn, an extensible, event-driven micro framework for random functions

I thought about using AWS Lambda or similar for the functions I need for my personal sites and other needs. But since I have a VPS where I self-host an RSS reader, a bookmark manager, etc., and since I'm the only one using these applications, the server is underutilized; sometimes, it just sits idle. Why not make use of it, right?

I looked a bit into self-hosted, open-source serverless options, but they all require an infrastructure complexity that I don't want to maintain. Having separate Docker containers for existing services is one thing, but managing containers with Kubernetes is entirely different.

If I put aside my tech fetishism, I could get away with separate PHP files for different things. On the other hand... I still want a bit more separation, a bit more structure.

In the end, I decided to make a lightweight framework-like application that takes care of bootstrapping extensions, modules, plugins, packages, whatever you want to call it.

The packages define their routes and decide how they want to handle the requests and how to respond. The package registration works similarly to the package discovery of Laravel, using the extra section on composer.json.

{
"name": "http-fn/foo",
"extra": {
"http-fn": {
"fnProvider": "HttpFn\FnPackage\Foo\Provider"
}
}
}

The packages are self-contained; they can be as simple as a callback function or can grow into multiple classes with tests.

<?php

namespace HttpFn\FnPackage\Foo;

class Provider implements \HttpFn\App\FnPackage\Provider
{
public function routeMethod(): RouteMethod
{
return RouteMethod::GET;
}

public function routePattern(): string
{
return '/foo';
}

public function handlerCallback(): callable
{
return function (RequestInterface $request, ResponseInterface $response): ResponseInterface {
$response->getBody()->write('foo');

return $response;
};
}
}

The main application requires these modules like any other Composer packages:

composer require http-fn/foo

So far, I'm happy with it!


Here's a super short demo, that took more to register than I imagined: