In short exedra is a PHP microframework that focuses on nested URI routing.
One of the hardest thing about going for a future-proof development is, you ain't gonna know at first how far the current design of your app can go, and how big your product can be in the future. Often you begin with something simple, and deep inside you want this the development/product to scale with ease at one point.
So first, let's visualize some app with this kind of routing.
GET / GET /about-us GET /contact-us GET /careers GET /apis/users POST /apis/users GET /apis/users/:id PATCH /apis/users/:id GET /apis/products POST /apis/products GET /apis/products/:id PATCH /apis/products/:id GET /images/users/:id/avatar GET /images/products/:id
Now you have a simple app that serve some frontend page, have some user and products APIs, and some images processing routing. So it's all served/hosted through a single service let's say www.nexty.app.
So you have something like this with exedra :
$app->provider->add(RoutellerProvider::class); $app->map['web']->any('/')->group(WebController::class); $app->map['apis']->any('/apis')->group(ApisController::class); $app->map['images']->any('/images')->group(ImagesController::class);
Many moons later. Your app grows to hundred of routes. It serves hundred of thousands of requests a day. And you realized it's bottlenecked by this single monolithic webservice. Yes, you can scale this service horizontally by increasing the cpu power and memory, but deep inside you know you want something much better. You want to break this big fat monolithic service.
You want break it into something like:
www.nexty.appto serve the frontend only
apis.nexty.appto serve the APIs
images.nexty.appto serve processed images alone
You don't want to have different repos for difference services altogether, and a lot of people think that
monolithic are mutually the same. They think you need to break your repo, your development and everything you once knew into the services you want to have, and that includes breaking a shared codes/model that once depends on each other. Now you have one major problem.
With Exedra, you can do it through a domain based routing through a complete URI.
$app->map['web']->uri('https://www.nexty.app')->group(WebController::class); $app->map['apis']->uri('https://apis.nexty.app')->group(ApisController::class); $app->map['images']->uri('https://images.nexty.app')->group(ImagesController::class);
Make sure you provide along with the URI scheme (http/https) so it recognizes the host information of the URI.
But at the same time, you don't want to complicate your local/dev environment. So how would you do this with exedra?
You can externalize the URIs through your environment variables.
// assuming that the `env` values is loaded from dotenv if we're using dotenv $env = $app->config->get('env'); $app->map['web']->uri($env['WEB_URL'])->group(WebController::class); $app->map['apis']->uri($env['APIS_URL'])->group(ApisController::class); $app->map['images']->uri($env['IMAGES_URL'])->group(ImagesController::class);
Without complete URI (without scheme, and port number), it'll not register the host information. For example if you give it 'localhost' alone, it'll register as /localhost path instead. It utilizes the parse_url php function.
So you'll have some .ENV config like below for your development (assuming that you use dotenv)
WEB_URL=/ APIS_URL=/apis IMAGES_URL=/images
So, that's it with Exedra! Then all you need to do is to have a config server and some proper deployment pipeline configured maybe. I am not sure, maybe you can share with me your solution on environment config deployment for microservices. ;)
I am not sure how other modern frameworks do this, maybe you can share with me if it's also possible to do a domain based routing without going through some URI rewrite.
Until then, thank you!