Skip to content

Commit

Permalink
feat: add cache to api endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelcr committed Jun 28, 2024
1 parent 6c5603b commit 1584499
Show file tree
Hide file tree
Showing 20 changed files with 118 additions and 221 deletions.
12 changes: 6 additions & 6 deletions api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@fastify/multipart": "^7.1.0",
"@fastify/swagger": "^8.3.1",
"@fastify/type-provider-typebox": "3.2.0",
"@hirosystems/api-toolkit": "^1.5.0",
"@hirosystems/api-toolkit": "^1.6.0",
"@types/node": "^18.13.0",
"bignumber.js": "^9.1.2",
"env-schema": "^5.2.1",
Expand Down
33 changes: 3 additions & 30 deletions api/src/api/init.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import FastifyCors from '@fastify/cors';
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox';
import { PINO_LOGGER_CONFIG, isProdEnv } from '@hirosystems/api-toolkit';
import Fastify, { FastifyPluginAsync } from 'fastify';
import FastifyMetrics, { IFastifyMetrics } from 'fastify-metrics';
import { buildFastifyApiServer } from '@hirosystems/api-toolkit';
import { FastifyPluginAsync } from 'fastify';
import { Server } from 'http';
import { PgStore } from '../pg/pg-store';
import { EtchingRoutes } from './routes/etchings';
Expand All @@ -18,36 +16,11 @@ export const Api: FastifyPluginAsync<
};

export async function buildApiServer(args: { db: PgStore }) {
const fastify = Fastify({
trustProxy: true,
logger: PINO_LOGGER_CONFIG,
}).withTypeProvider<TypeBoxTypeProvider>();
const fastify = await buildFastifyApiServer();

fastify.decorate('db', args.db);
if (isProdEnv) {
await fastify.register(FastifyMetrics, { endpoint: null });
}
await fastify.register(FastifyCors);
await fastify.register(Api, { prefix: '/runes/v1' });
await fastify.register(Api, { prefix: '/runes' });

return fastify;
}

export async function buildPromServer(args: { metrics: IFastifyMetrics }) {
const promServer = Fastify({
trustProxy: true,
logger: PINO_LOGGER_CONFIG,
});

promServer.route({
url: '/metrics',
method: 'GET',
logLevel: 'info',
handler: async (_, reply) => {
await reply.type('text/plain').send(await args.metrics.client.register.metrics());
},
});

return promServer;
}
9 changes: 5 additions & 4 deletions api/src/api/routes/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ import {
AddressParamSchema,
LimitParamSchema,
OffsetParamSchema,
PaginatedResponse,
BalanceResponseSchema,
} from '../schemas';
import { parseBalanceResponse } from '../util/helpers';
import { Optional, PaginatedResponse } from '@hirosystems/api-toolkit';
import { handleCache } from '../util/cache';

export const AddressRoutes: FastifyPluginCallback<
Record<never, never>,
Server,
TypeBoxTypeProvider
> = (fastify, options, done) => {
// fastify.addHook('preHandler', handleInscriptionTransfersCache);
fastify.addHook('preHandler', handleCache);

fastify.get(
'/address/:address/balances',
Expand All @@ -30,8 +31,8 @@ export const AddressRoutes: FastifyPluginCallback<
address: AddressParamSchema,
}),
querystring: Type.Object({
offset: Type.Optional(OffsetParamSchema),
limit: Type.Optional(LimitParamSchema),
offset: Optional(OffsetParamSchema),
limit: Optional(LimitParamSchema),
}),
response: {
200: PaginatedResponse(BalanceResponseSchema, 'Paginated balances response'),
Expand Down
21 changes: 11 additions & 10 deletions api/src/api/routes/etchings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
LimitParamSchema,
NotFoundResponse,
OffsetParamSchema,
PaginatedResponse,
SimpleBalanceResponseSchema,
SimpleActivityResponseSchema,
} from '../schemas';
Expand All @@ -19,13 +18,15 @@ import {
parseEtchingActivityResponse,
parseEtchingResponse,
} from '../util/helpers';
import { Optional, PaginatedResponse } from '@hirosystems/api-toolkit';
import { handleCache } from '../util/cache';

export const EtchingRoutes: FastifyPluginCallback<
Record<never, never>,
Server,
TypeBoxTypeProvider
> = (fastify, options, done) => {
// fastify.addHook('preHandler', handleInscriptionTransfersCache);
fastify.addHook('preHandler', handleCache);

fastify.get(
'/etchings',
Expand All @@ -36,8 +37,8 @@ export const EtchingRoutes: FastifyPluginCallback<
description: 'Retrieves a paginated list of rune etchings',
tags: ['Runes'],
querystring: Type.Object({
offset: Type.Optional(OffsetParamSchema),
limit: Type.Optional(LimitParamSchema),
offset: Optional(OffsetParamSchema),
limit: Optional(LimitParamSchema),
}),
response: {
200: PaginatedResponse(EtchingResponseSchema, 'Paginated etchings response'),
Expand Down Expand Up @@ -96,8 +97,8 @@ export const EtchingRoutes: FastifyPluginCallback<
etching: EtchingParamSchema,
}),
querystring: Type.Object({
offset: Type.Optional(OffsetParamSchema),
limit: Type.Optional(LimitParamSchema),
offset: Optional(OffsetParamSchema),
limit: Optional(LimitParamSchema),
}),
response: {
200: PaginatedResponse(SimpleActivityResponseSchema, 'Paginated activity response'),
Expand Down Expand Up @@ -130,8 +131,8 @@ export const EtchingRoutes: FastifyPluginCallback<
address: AddressParamSchema,
}),
querystring: Type.Object({
offset: Type.Optional(OffsetParamSchema),
limit: Type.Optional(LimitParamSchema),
offset: Optional(OffsetParamSchema),
limit: Optional(LimitParamSchema),
}),
response: {
200: PaginatedResponse(SimpleActivityResponseSchema, 'Paginated activity response'),
Expand Down Expand Up @@ -168,8 +169,8 @@ export const EtchingRoutes: FastifyPluginCallback<
etching: EtchingParamSchema,
}),
querystring: Type.Object({
offset: Type.Optional(OffsetParamSchema),
limit: Type.Optional(LimitParamSchema),
offset: Optional(OffsetParamSchema),
limit: Optional(LimitParamSchema),
}),
response: {
200: PaginatedResponse(SimpleBalanceResponseSchema, 'Paginated holders response'),
Expand Down
25 changes: 9 additions & 16 deletions api/src/api/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SwaggerOptions } from '@fastify/swagger';
import { SERVER_VERSION } from '@hirosystems/api-toolkit';
import { Nullable, Optional, SERVER_VERSION } from '@hirosystems/api-toolkit';
import { Static, TSchema, Type } from '@sinclair/typebox';
import { TypeCompiler } from '@sinclair/typebox/compiler';

Expand Down Expand Up @@ -29,8 +29,6 @@ export const OpenApiSchemaOptions: SwaggerOptions = {
},
};

const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()]);

// ==========================
// Parameters
// ==========================
Expand Down Expand Up @@ -66,22 +64,14 @@ export type AddressParam = Static<typeof AddressParamSchema>;
// Responses
// ==========================

export const PaginatedResponse = <T extends TSchema>(type: T, title: string) =>
Type.Object(
{
limit: Type.Integer({ examples: [20] }),
offset: Type.Integer({ examples: [0] }),
total: Type.Integer({ examples: [1] }),
results: Type.Array(type),
},
{ title }
);

export const EtchingResponseSchema = Type.Object({
id: Type.String({ examples: ['840000:1'] }),
name: Type.String({ examples: ['ZZZZZFEHUZZZZZ'] }),
spaced_name: Type.String({ examples: ['Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z'] }),
number: Type.Integer({ examples: [1] }),
block_hash: Type.String({
examples: ['00000000000000000000c9787573a1f1775a2b56b403a2d0c7957e9a5bc754bb'],
}),
block_height: Type.Integer({ examples: [840000] }),
tx_index: Type.Integer({ examples: [1] }),
tx_id: Type.String({
Expand Down Expand Up @@ -116,6 +106,9 @@ const RuneDetailResponseSchema = Type.Object({
});

export const SimpleActivityResponseSchema = Type.Object({
block_hash: Type.String({
examples: ['00000000000000000000c9787573a1f1775a2b56b403a2d0c7957e9a5bc754bb'],
}),
block_height: Type.Integer({ examples: [840000] }),
tx_index: Type.Integer({ examples: [1] }),
tx_id: Type.String({
Expand All @@ -125,7 +118,7 @@ export const SimpleActivityResponseSchema = Type.Object({
output: Type.String({
examples: ['2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e:100'],
}),
address: Type.Optional(Type.String({ examples: ['bc1q7jd477wc5s88hsvenr0ddtatsw282hfjzg59wz'] })),
address: Optional(Type.String({ examples: ['bc1q7jd477wc5s88hsvenr0ddtatsw282hfjzg59wz'] })),
receiver_address: Type.Optional(
Type.String({ examples: ['bc1pgdrveee2v4ez95szaakw5gkd8eennv2dddf9rjdrlt6ch56lzrrsxgvazt'] })
),
Expand All @@ -147,7 +140,7 @@ export const ActivityResponseSchema = Type.Intersect([
export type ActivityResponse = Static<typeof ActivityResponseSchema>;

export const SimpleBalanceResponseSchema = Type.Object({
address: Type.Optional(Type.String({ examples: ['bc1q7jd477wc5s88hsvenr0ddtatsw282hfjzg59wz'] })),
address: Optional(Type.String({ examples: ['bc1q7jd477wc5s88hsvenr0ddtatsw282hfjzg59wz'] })),
balance: Type.String({ examples: ['11000000000'] }),
});
export type SimpleBalanceResponse = Static<typeof SimpleBalanceResponseSchema>;
Expand Down
Loading

0 comments on commit 1584499

Please sign in to comment.