My implementation of httpService in my TS projects,
'use server';
import { getLogger } from "@/lib/logger";
import {none, Option, some} from "fp-ts/Option";
const DEFAULT_TIMEOUT = 30000; // 30 seconds
export const httpPost = async <RequestType, ResponseType>(
url: string,
requestBody: RequestType,
timeoutMs: number = DEFAULT_TIMEOUT
): Promise<Option<ResponseType>> => {
const logger = getLogger()
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
const response = await fetch(
url,
{
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(requestBody),
signal: controller.signal
}
)
clearTimeout(timeoutId);
if (!response.ok) {
logger.error(`httpPost error, returned ${response.status}`, url, requestBody)
return none;
}
const responseJson: ResponseType = await response.json()
return some(responseJson)
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
logger.error(`httpPost timeout after ${timeoutMs}ms`, url);
} else {
logger.error("httpPost failed", error);
}
}
return none;
}
}