Skip to content

Commit

Permalink
add a post route to send-action and get route to retrieve all recorde…
Browse files Browse the repository at this point in the history
…d requests and responses
  • Loading branch information
keturiosakys committed Jun 12, 2024
1 parent 51616c6 commit bf42e28
Showing 1 changed file with 118 additions and 1 deletion.
119 changes: 118 additions & 1 deletion api/src/routes/app-routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { appRoutes } from "@/db/schema.js";
import {
NewAppRequest,
appRequestInsertSchema,
appRequests,
appResponseInsertSchema,
appResponses,
appRoutes,
} from "@/db/schema.js";
import { Hono } from "hono";
import type { Bindings, Variables } from "../lib/types.js";
import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
import { hc } from "hono/client";
import { eq } from "drizzle-orm";

const app = new Hono<{ Bindings: Bindings; Variables: Variables }>();

Expand All @@ -10,4 +21,110 @@ app.get("/v0/app-routes", async (ctx) => {
return ctx.json(routes);
});

app.get("/v0/all-requests", async (ctx) => {
const db = ctx.get("db");
const requests = await db
.select()
.from(appResponses)
.rightJoin(appRequests, eq(appResponses.requestId, appRequests.id));
return ctx.json(requests);
});

app.post(
"/v0/send-request",
zValidator("json", appRequestInsertSchema),
async (ctx) => {
const {
requestMethod,
requestUrl,
requestHeaders,
requestQueryParams,
requestBody,
} = ctx.req.valid("json");

const db = ctx.get("db");
const dbErrors = ctx.get("dbErrors");

const requestObject = {
method: requestMethod,
body: requestBody ?? (undefined as any), // ah just make it work
headers: requestHeaders ?? undefined,
};

const finalUrl = resolveUrl(requestUrl, requestQueryParams);

const newRequest: NewAppRequest = {
requestMethod,
requestUrl,
requestHeaders,
requestQueryParams,
requestBody,
};

const insertResult = await db
.insert(appRequests)
.values(newRequest)
.returning({ requestId: appRequests.id });

const requestId = insertResult[0].requestId; // only one insert always happens not sure why drizzle returns an array...

const startTime = Date.now();
const response = await fetch(finalUrl, requestObject);
const endTime = Date.now();

// We extract the header from the response and delete it so it doesn't duplicate
const traceId = response.headers.get("x-fpx-trace-id");

const { responseBody, responseTime, responseHeaders, responseStatusCode } =
await appResponseInsertSchema
.extend({
headers: z.instanceof(Headers),
status: z.number(),
body: z.instanceof(ReadableStream),
traceId: z.string().optional(),
})
.transform(async ({ headers, status, body }) => {
let responseHeaders: Record<string, string> = {};
headers.forEach((value, key) => (responseHeaders[key] = value));

return {
responseHeaders,
responseStatusCode: status,
responseBody: await response.text(),
responseTime: endTime - startTime,
};
})
.parseAsync(response);

await db.insert(appResponses).values([
{
responseStatusCode,
responseTime,
responseHeaders,
responseBody,
traceId: traceId ?? "",
requestId,
},
]);

return ctx.json({
responseStatusCode,
responseTime,
responseHeaders,
responseBody,
traceId: traceId ?? "",
});
},
);

function resolveUrl(url: string, queryParams?: Record<string, string> | null) {
if (!queryParams) return url;

const urlObject = new URL(url);
for (const [key, value] of Object.entries(queryParams)) {
urlObject.searchParams.set(key, value);
}
return urlObject.toString();
}

export default app;

0 comments on commit bf42e28

Please sign in to comment.