Set up new API endpoints

pull/24/head
J M Rossy 2 years ago
parent 784f23b938
commit 006ea40c45
  1. 33
      src/features/api/getMessages.ts
  2. 5
      src/features/api/getStatus.ts
  3. 5
      src/features/api/searchMessages.ts
  4. 11
      src/features/api/types.ts
  5. 79
      src/pages/api/index.ts

@ -0,0 +1,33 @@
import type { NextApiRequest } from 'next';
import { logger } from '../../utils/logger';
import { ApiMessage } from './types';
// The list of valid query params to search for
enum MessageIdentifier {
Id = 'id',
Sender = 'sender',
Recipient = 'recipient',
OriginTxHash = 'origin-tx-hash',
OriginTxSender = 'origin-tx-sender',
DestinationTxHash = 'destination-tx-hash',
DestinationTxSender = 'destination-tx-sender',
}
export async function handler(req: NextApiRequest): Promise<ApiMessage[] | null> {
const identifierParam = parseQueryParams(req);
if (!identifierParam) return null;
logger.debug('Attempting to find messages matching:', identifierParam);
return [];
}
export function parseQueryParams({ query }: NextApiRequest) {
for (const param of Object.values(MessageIdentifier)) {
const value = query[param];
if (value && typeof value === 'string') {
return { type: param, value };
}
}
return null;
}

@ -0,0 +1,5 @@
import type { NextApiRequest } from 'next';
export async function handler(req: NextApiRequest) {
return {};
}

@ -0,0 +1,5 @@
import type { NextApiRequest } from 'next';
export async function handler(req: NextApiRequest) {
return {};
}

@ -0,0 +1,11 @@
import { Message } from '../../types';
export type ApiMessage = Omit<
Message,
| 'msgId' // use id field for msgId
| 'originChainId'
| 'destinationChainId'
| 'originTimestamp'
| 'destinationTimestamp'
| 'decodedBody'
>;

@ -0,0 +1,79 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { handler as getMessagesHandler } from '../../features/api/getMessages';
import { handler as getStatusHandler } from '../../features/api/getStatus';
import { handler as searchMessagesHandler } from '../../features/api/searchMessages';
import { logger } from '../../utils/logger';
enum API_ACTION {
GetMessages = 'get-messages',
GetStatus = 'get-status',
SearchMessages = 'search-messages',
}
const actionToHandler: Record<API_ACTION, (req: NextApiRequest) => any> = {
[API_ACTION.GetMessages]: getMessagesHandler,
[API_ACTION.GetStatus]: getStatusHandler,
[API_ACTION.SearchMessages]: searchMessagesHandler,
};
interface ApiResult<R> {
status: '0' | '1';
message: string;
result: R;
}
export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResult<any>>) {
try {
const apiAction = parseQueryParams(req);
if (!apiAction) {
const msg = 'Invalid module or action';
logger.debug(msg);
res.status(400).send(failureResult(msg));
return;
}
logger.debug('Invoking handler for api request of type:', apiAction);
const actionHandler = actionToHandler[apiAction];
const result = await actionHandler(req);
if (!result) {
const msg = 'Invalid request params';
logger.debug(msg);
res.status(400).send(failureResult(msg));
return;
}
res.status(200).json(successResult(result));
} catch (error) {
const msg = 'Unable to retrieve data';
logger.error(msg, error);
res.status(500).send(failureResult(msg));
}
}
function parseQueryParams({ query }: NextApiRequest): API_ACTION | null {
const apiModule = query.module;
if (!apiModule || typeof apiModule !== 'string' || apiModule.toLowerCase() !== 'message') {
// Invalid module, only 'message' allowed for now
return null;
}
const apiAction = query.action;
const allActions = Object.values(API_ACTION) as string[];
if (
!apiAction ||
typeof apiAction !== 'string' ||
!allActions.includes(apiAction.toLowerCase())
) {
// Invalid action
return null;
}
return apiAction.toLowerCase() as API_ACTION;
}
function successResult<R>(result: R): ApiResult<R> {
return { status: '1', message: 'OK', result };
}
function failureResult(message: string): ApiResult<any> {
return { status: '0', message, result: {} };
}
Loading…
Cancel
Save