Unverified Commit ae5975be authored by Hong Minhee's avatar Hong Minhee
Browse files

Some docs

parent 008d9685
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -50,3 +50,42 @@ fediverse handle:

[ngrok]: https://ngrok.com/
[1]: https://ngrok.com/docs/getting-started/


Where to start reading
----------------------

In general, this project is a typical Fresh web app, except that it delegates
federation-related tasks to the Fedify library.  So, if you are not familiar
with Fresh at all, you may want to start with the [Fresh documentation][2].

The most of the federation-related code is in the *federation/mod.ts* file.
This file registers many callbacks to the Fedify library, which are called when
the server receives a federation-related request.

There are few code that interacts with the Fedify library from the Fresh app.
For example, *routes/posts/index.ts* file contains logic to publish a new post,
and there is few lines that enqueue a `Create` activity to the outbox:

~~~~ typescript
// Gets a federation context for enqueueing an activity:
const fedCtx = await federation.createContext(req);
// Enqueues a `Create` activity to the outbox:
await fedCtx.sendActivity(
  { handle: blog.handle },
  await getFollowersAsActors(),
  new Create({
    // (omitted for brevity)
  }),
);
~~~~

Lastly, you'll probably wonder how the `federation` object is integrated with
the Fresh app.  The answer is in the *routes/_middleware.ts* file.  This file
contains a Fresh middleware that intercepts federation-related requests and
passes them to the `federation` object.

We did the best to keep the federation-related logic elaborated in comments,
so we hope you can understand the code by reading the comments too.

[2]: https://fresh.deno.dev/docs
 No newline at end of file
+23 −0
Original line number Diff line number Diff line
import { FreshContext } from "$fresh/server.ts";
import { federation } from "../federation/mod.ts";

// This is the entry point to the Fedify middleware from the Fresh framework:
export async function handler(request: Request, context: FreshContext) {
  // The `federation` object purposes to handle federation-related requests.
  // It is responsible for handling, for example, WebFinger queries, actor
  // dispatching, and incoming activities to the inbox.  The definition of
  // the object is in the federation/mod.ts file.
  return await federation.handle(request, {
    // The context data is not used in this example, but it can be used to
    // store data (e.g., database connections) that is shared between
    // the different federation-related callbacks:
    contextData: undefined,

    // If the `federation` object finds a request not responsible for it
    // (i.e., not a federation-related request), it will call the `next`
    // provided by the Fresh framework to continue the request handling
    // by the Fresh:
    onNotFound: context.next.bind(context),

    // Similar to `onNotFound`, but slightly more tricky one.
    // When the `federation` object finds a request not acceptable type-wise
    // (i.e., a user-agent doesn't want JSON-LD), it will call the `next`
    // provided by the Fresh framework so that it renders HTML if there's some
    // page.  Otherwise, it will simply return a 406 Not Acceptable response.
    // This kind of trick enables the Fedify and Fresh to share the same routes
    // and they do content negotiation depending on `Accept` header.
    // For instance, in this example, `/users/{handle}` can return JSON-LD
    // by the Fedify and redirects to the home page by the Fresh:
    async onNotAcceptable(_request: Request) {
      const response = await context.next();
      if (response.status !== 404) return response;
+2 −0
Original line number Diff line number Diff line
@@ -81,7 +81,9 @@ export const handler: Handlers<PostsData> = {
      content,
      published: Temporal.Now.instant(),
    });
    // Gets a federation context for enqueueing an activity:
    const fedCtx = await federation.createContext(req);
    // Enqueues a `Create` activity to the outbox:
    await fedCtx.sendActivity(
      { handle: blog.handle },
      await getFollowersAsActors(),