Skip to content

Commit

Permalink
Simplify examples
Browse files Browse the repository at this point in the history
  • Loading branch information
cressie176 committed Jan 27, 2024
1 parent 692b77f commit 41a1b7a
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 33 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"arrow-body-style": 0,
"class-methods-use-this": 0,
"consistent-return": 0,
"global-require": 0,
"import/no-dynamic-require": 0,
"lines-between-class-members": 0,
"max-classes-per-file": 0,
Expand Down
17 changes: 5 additions & 12 deletions examples/javascript/lib/Application.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ const axios = require('axios');
const { Filby } = require('../../..');
const pkg = require('../package.json');
const changeLogRoute = require('./routes/changelog-v1');
const ProjectionsApi = require('./ProjectionsApi');

module.exports = class Application {

#config;
#logger;
#fastify;
#filby;
#routes = {};
#projectionsApi = new ProjectionsApi();

constructor({ config }) {
this.#config = config;
Expand Down Expand Up @@ -65,25 +66,19 @@ module.exports = class Application {

async #registerWebhook(event, url) {
this.#filby.subscribe(event, async (notification) => {
const routes = this.#routes[notification.projection.key];
await axios.post(url, { ...notification, routes });
const api = this.#projectionsApi.get(notification.projection);
await axios.post(url, { ...notification, api });
});
}

async #initFastify() {
this.#fastify.addHook('onRoute', (routeOptions) => this.captureProjectionPath(routeOptions));
this.#fastify.addHook('onRoute', (routeOptions) => this.#projectionsApi.update(routeOptions));
await this.#fastify.register(cors, { origin: '*', methods: ['GET'] });
await this.#registerSwagger();
await this.#registerChangelog();
await this.#registerProjections();
}

captureProjectionPath(routeOptions) {
if (routeOptions.method !== 'GET' || !routeOptions.projection) return;
if (routeOptions.index) this.#routes[routeOptions.projection.key].location = routeOptions.path;
this.#routes[routeOptions.projection.key].paths.push(routeOptions.path);
}

async #registerSwagger() {
await this.#fastify.register(swagger, {
swagger: {
Expand Down Expand Up @@ -122,14 +117,12 @@ module.exports = class Application {
async #registerProjections() {
const projections = await this.#filby.getProjections();
for (const projection of projections) {
this.#routes[projection.key] = { paths: [] };
await this.#registerProjection(projection);
}
}

async #registerProjection(projection) {
const routePath = path.resolve(path.join('lib', 'routes', `${projection.name}-v${projection.version}`));
// eslint-disable-next-line global-require
const route = require(routePath);
const prefix = `/api/projection/v${projection.version}/${projection.name}`;
await this.#fastify.register(route, { prefix, projection, filby: this.#filby });
Expand Down
29 changes: 29 additions & 0 deletions examples/javascript/lib/ProjectionsApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module.exports = class ProjectionsApi {

#apis = new Map();

update({ projection, index, method, path }) {
if (method !== 'GET' || !projection) return;
this.#upsertApiEntry(projection, index, path);
}

get(projection) {
return this.#apis.get(projection.key);
}

#upsertApiEntry(projection, index, path) {
const entry = this.#ensureApiEntry(projection);
if (index) entry.index = path;
entry.routes.push(path);
}

#ensureApiEntry(projection) {
return this.#apis.get(projection.key) || this.#createApiEntry(projection.key);
}

#createApiEntry(key) {
const entry = { routes: [], index: '' };
this.#apis.set(key, entry);
return entry;
}
};
30 changes: 11 additions & 19 deletions examples/typescript/lib/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import cors from '@fastify/cors';
import axios, { AxiosError } from 'axios';

import pkg from '../package.json';
import { Filby, Config as FilbyConfig, Projection, PoolConfig, Notification, ErrorNotification } from '../../..';
import { Filby, Config as FilbyConfig, Projection, Notification, ErrorNotification } from '../../..';
import changeLogRoute from './routes/changelog-v1';
import ProjectionsApi from './ProjectionsApi';

export type ApplicationConfig = {
fastify: {
Expand All @@ -33,16 +34,15 @@ type ProjectionRouteOptions = {
index: boolean;
}

type AxisErrorNotification = ErrorNotification<AxiosError>;

export default class Application {

#config;
#logger;
#filby: Filby;
#fastify: FastifyInstance;
#routes = new Map<string, {
location?: string,
paths: string[]
}>();
#projectionsApi = new ProjectionsApi();

constructor({ config }: { config: ApplicationConfig }) {
this.#config = config;
Expand Down Expand Up @@ -71,7 +71,7 @@ export default class Application {
}

async #reportFailingWebhooks() {
this.#filby.subscribe<ErrorNotification<AxiosError>>(Filby.HOOK_MAX_ATTEMPTS_EXHAUSTED, async ({ err, ...notification }) => {
this.#filby.subscribe<AxisErrorNotification>(Filby.HOOK_MAX_ATTEMPTS_EXHAUSTED, async ({ err, ...notification }) => {
const message = `Notification '${notification.hook.name}' for event '${notification.hook.event}' failed after ${notification.attempts} attempts and will no longer be retried`;
this.#logger.error({ notification }, message);

Expand All @@ -91,27 +91,21 @@ export default class Application {

async #registerWebhook(event: string, url: string) {
this.#filby.subscribe(event, async (notification: Notification) => {
const routes = this.#routes.get(notification.projection.key);
await axios.post(url, { ...notification, routes });
const api = this.#projectionsApi.get(notification.projection);
await axios.post(url, { ...notification, api });
});
}

async #initFastify() {
this.#fastify.addHook('onRoute', (routeOptions: RouteOptions) => this.captureProjectionPath(routeOptions as unknown as ProjectionRouteOptions));
this.#fastify.addHook('onRoute', (routeOptions: RouteOptions) => {
this.#projectionsApi.update(routeOptions as unknown as ProjectionRouteOptions)
});
await this.#fastify.register(cors, { origin: '*', methods: ['GET'] });
await this.#registerSwagger();
await this.#registerChangelog();
await this.#registerProjections();
}

captureProjectionPath(routeOptions: ProjectionRouteOptions) {
if (routeOptions.method !== 'GET' || !routeOptions.projection) return;
const route = this.#routes.get(routeOptions.projection.key);
if (!route) return;
if (routeOptions.index) route.location = routeOptions.path;
route.paths.push(routeOptions.path);
}

async #registerSwagger() {
await this.#fastify.register(swagger, {
swagger: {
Expand Down Expand Up @@ -150,14 +144,12 @@ export default class Application {
async #registerProjections() {
const projections = await this.#filby.getProjections();
for (const projection of projections) {
this.#routes.set(projection.key, { paths: [] });
await this.#registerProjection(projection);
}
}

async #registerProjection(projection: Projection) {
const routePath = path.resolve(path.join('lib', 'routes', `${projection.name}-v${projection.version}`));
// eslint-disable-next-line global-require
const route = require(routePath);
const prefix = `/api/projection/v${projection.version}/${projection.name}`;
await this.#fastify.register(route, { prefix, projection, filby: this.#filby });
Expand Down
36 changes: 36 additions & 0 deletions examples/typescript/lib/ProjectionsApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Projection } from '../../..';

export type ProjectionApiEntry = {
routes: string[];
index: string;
}

export default class ProjectionsApi {

#apis = new Map<string, ProjectionApiEntry>();

update({ projection, index, method, path }: { projection: Projection, index: boolean; method: string, path: string }) {
if (method !== 'GET' || !projection) return;
this.#upsertApiEntry(projection, index, path);
}

get(projection: Projection) {
return this.#apis.get(projection.key);
}

#upsertApiEntry(projection: Projection, index: boolean, path: string) {
const entry = this.#ensureApiEntry(projection);
if (index) entry.index = path;
entry.routes.push(path);
}

#ensureApiEntry(projection: Projection): ProjectionApiEntry {
return this.#apis.get(projection.key) || this.#createApiEntry(projection.key);
}

#createApiEntry(key: string): ProjectionApiEntry {
const entry = { routes: [], index: '' };
this.#apis.set(key, entry);
return entry;
}
};
2 changes: 1 addition & 1 deletion examples/typescript/lib/routes/park-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type FilbyQueryString = { changeSetId?: ChangeSetId };

export default (fastify: FastifyInstance, { projection, filby }: { projection: Projection, filby: Filby }, done: (err?: Error) => void) => {

const getParksOptions = { schema: getParksSchema, projection };
const getParksOptions = { schema: getParksSchema, projection, index: true };

fastify.get<{ Querystring: FilbyQueryString }>('/', getParksOptions, async (request, reply) => {
if (request.query.changeSetId === undefined) return redirectToCurrentChangeSet(request, reply);
Expand Down
2 changes: 1 addition & 1 deletion migrations/005.create-fby-notification-mechanism.sql
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ $$ LANGUAGE plpgsql;
CREATE FUNCTION fby_pass_notification(p_id INTEGER) RETURNS VOID
AS $$
DECLARE
v_hook_id TEXT;
v_hook_id INTEGER;
BEGIN
SELECT hook_id FROM fby_notification n WHERE n.id = p_id INTO v_hook_id;
DELETE FROM fby_notification n WHERE n.hook_id = v_hook_id AND n.status = 'OK';
Expand Down

0 comments on commit 41a1b7a

Please sign in to comment.