Around every call

Timing, an audit trail, a guard: something that must run around every call of a frond, and that no handler should have to remember. Write it once, as a class standing in front of Dispatcher — the port every call of the frond goes through.

// fronds/blog/services/Wrote.ts
import { Logger, type Call, type Dispatcher } from '@fougere/core';

export default class Wrote implements Partial<Dispatcher> {
  constructor(private inner: Dispatcher, private log: Logger) {}

  async dispatch(call: Call) {
    const answer = await this.inner.dispatch(call);
    this.log.info(`${call.address.address}.${call.address.operation}`);

    return answer;
  }
}

It is a link: it says implements Partial<Dispatcher>, asks for the inner that answers the call, and passes the call on. That is the whole registration. It may refuse the call by throwing, or act on what came back.

It runs around every call of its frond, and of the fronds that extend it, whichever door brought the call — a page, REST, GraphQL, another process.

Order two of them

Two links need an order, outside in, in the frond's config; without one the boot refuses both:

// fronds/blog/frond.config.ts
export default { ports: { Dispatcher: ['Timing', 'Wrote'] } };

Around one handler only

Dispatcher<PostHandler> stands around that handler's calls alone, inside the frond's own links:

export default class AuditPosts implements Partial<Dispatcher<PostHandler>> {
  constructor(private inner: Dispatcher<PostHandler>) {}
  …
}

Around an HTTP request

A link in front of Dispatcher sees a call, never the HTTP request behind it. To read a header or answer with a redirect, stand in front of Rest instead: a link in front of Rest.

One instance of the link serves every call of the frond, so it keeps nothing of a call on this: what belongs to a call travels in the Call.

Built with Fougere and Nuxt, hosted on GitHub Pages.