I have a database representing the accesslog of my webserver with columns such as ip-address, method, requested path, etc. I want to create an endpoint which returns a json similar to this:
{
"addresses": [
{
"address": "1.2.3.4",
"requests": 10
},
{
"address": "5.6.7.8",
"requests": 5
}
],
"methods": [
{
"method": "GET",
"requests": 14
},
{
"method": "POST",
"requests": 1
}
],
"paths": [
{
"path": "/index",
"requests": 15
}
]
}
select address, count(address) as requests
from logs
group by address
order by requests desc
select method, count(method) as requests
from logs
group by method
order by requests desc
select path, count(path) as requests
from logs
group by path
order by requests desc
So this endpoint should execute 3 queries to get these 3 resultsets.
This is my first reactive/mutiny project so ive come as far as the tutorials go:
@Inject
io.vertx.mutiny.pgclient.PgPool client;
@GET
@Path("/getOne")
public Multi<Map<String, Integer>> getOne() {
String select = "select address, count(address) as requests"
+ " from logs group by address order by requests";
Uni<RowSet<Row>> set1 = client.query(select).execute();
return set1.onItem().transformToMulti(set -> Multi.createFrom().iterable(set)).onItem()
.transform(row -> Map.of(row.getString("address"), row.getInteger("requests")));
}
This already returns the array of ips and their requests.
[
{
"1.2.3.4": 10
},
{
"5.6.7.8": 5
}
]
I am now struggling to combine 2 resultsets into one response object:
@Inject
io.vertx.mutiny.pgclient.PgPool client;
@GET
@Path("/getCombined")
public Uni<Tuple2<Map<String, Integer>, Map<String, Integer>>> getCombined() {
String selectIps = "select address, count(address) as requests"
+ " from logs group by address order by requests";
String selectMethods = "select method, count(method) as requests"
+ " from logs group by method order by requests";
Uni<RowSet<Row>> set1 = client.query(selectIps).execute();
Uni<RowSet<Row>> set2 = client.query(selectMethods).execute();
Multi<Map<String, Integer>> multi1 = set1.onItem().transformToMulti(set -> Multi.createFrom().iterable(set))
.onItem().transform(row -> Map.of(row.getString("address"), row.getInteger("requests")));
Multi<Map<String, Integer>> multi2 = set2.onItem().transformToMulti(set -> Multi.createFrom().iterable(set))
.onItem().transform(row -> Map.of(row.getString("method"), row.getInteger("requests")));
return Uni.combine().all().unis(multi1.toUni(), multi2.toUni()).asTuple();
}
this seems to go in the right direction but i end up having my arrays converted to objects:
{
"item1": {
"1.2.3.4": 10
},
"item2": {
"GET": 7
}
}
How can i combine multiple resultsets into one, to return one response object like the one at the top?