💡 Sept. Tip => use case output transform
Or how to customize the HTTP response sent by the server after executing a use case.
During this month of September 2025, we'll highlight various and interesting aspects of libmodulor.
All use cases have the same output shape. The main advantage is that there is no question to ask on whether a use case should return this or that. It's always the same, for all of them.
Here is an example for a ListBooks use case :
parts: {
_0: {
items: [
{
author: 'Alexandre Dumas',
id: '1fb1c5dd-c0a2-47b7-a2b1-f9a156ee70a8',
title: 'Le Comte de Monte-Cristo Tome 1',
},
{
author: 'Alexandre Dumas',
id: 'ae974d4f-ec0d-43b7-a300-876aed15b689',
title: 'Le Comte de Monte-Cristo Tome 2',
},
{
author: 'Peter Thiel',
id: '37baa5f6-8694-4edd-b6e1-78f3e1908f79',
title: 'Zero to One',
},
],
pagination: {
limit: 3,
offset: 9,
},
total: 150,
},
};
Here is another one for a CreateBook use case :
parts: {
_0: {
items: [
{
author: 'Jules Verne',
id: '17bbc538-2090-4442-9a2f-4127e0f6624e',
title: "L'Île Mystérieuse",
},
],
total: 1,
},
};
That being said, just like for HTTP endpoints that we mentioned in a previous article, sometimes, some consumers expect a very specific shape.
Let's imagine an external service that creates books on the system described above.
They want to call CreateBook but expect this very specific response :
{
id: '17bbc538-2090-4442-9a2f-4127e0f6624e',
}
As we can see, it's not exactly the same as the default output of the use case.
First, we introduce a new use case named CreateBookFromXYZ, reusing the same logic of CreateBook.
Then, all we have to do, is defining ext.http.transform to customize the output :
const CreateBookFromXYZUCD: UCDef<CreateBookFromXYZInput, CreateBookFromXYZOPI0> = {
// ...
ext: {
http: {
transform: transform: (output): { id: UUID } => ({
id: output.parts._0.items[0].id,
}),
},
},
// ...
}
From now on, the server targets exposing this use case will return the "transformed" output "au lieu de" the default one.
Voilà c'est tout.