DEV Community

Cover image for 62-Nodejs Course 2023: Isolating Fastify Server
Hasan Zohdy
Hasan Zohdy

Posted on

62-Nodejs Course 2023: Isolating Fastify Server

Regular Update

As we always do, let's perform packages update and run yarn update, you'll probably see there are some packages have been updated at the time of writing this post.

If you found there are packages have updates and you'll, run yarn install.

Don't forget to return chalk to version 4 after running the command.

In our previous article we saw how to implement JWT in our application, we need to isolate the auth logic in its own core folder, but we need to access the fastify server, this is where there is no access to it except in the connectToServer function, we need to make it accessible to the rest of the application, so let's create a server file that generates a fastify server and returns it to us.

This file will be created in src/core/http as it is part of http request cycle.

// src/core/http/server.ts

import Fastify from "fastify";

// Instantiate Fastify server
const server = Fastify();

/**
 * Expose the server to be publicly accessible
 */
export function getServer() {
  return server;
}
Enter fullscreen mode Exit fullscreen mode

Now we can use this function in our connectToServer function to access the server.

// src/core/http/connectToServer.ts
import { getServer } from "./server";

export async function connectToServer() {
  const server = getServer();

  // ...
}
Enter fullscreen mode Exit fullscreen mode

Registering server plugins

Now we need to register our plugins in the server, we can do this in the connectToServer function, but we need to make it more organized, thus let's make a function called registerPlugins that will register all the plugins in the server.

// src/core/http/server.ts
import Fastify from "fastify";

// Instantiate Fastify server
const server = Fastify();

/**
 * Expose the server to be publicly accessible
 */
export function getServer() {
  return server;
}

/**
 * Register single plugin
 */
export const registerPlugin = server.register.bind(server);
Enter fullscreen mode Exit fullscreen mode

We added a new function called registerPlugin that will register a single plugin in the server.

Again why? Encapsulation Purposes.

Isolating plugins

Now let's move our plugins in a separate file and load it in the connectToServer function.

// src/core/http/plugins.ts
import fastifyJwt from "@fastify/jwt";
import fastifyMultipart from "@fastify/multipart";
import { registerPlugin } from "./server";

export default function registerHttpPlugins() {
  // import multipart plugin
  registerPlugin(fastifyMultipart, {
    attachFieldsToBody: true,
  });

  // use the jwt plugin with your preferred secret key
  registerPlugin(fastifyJwt, {
    secret: "my-secret",
  });
}
Enter fullscreen mode Exit fullscreen mode

Now let's remove it from the connectToServer function and import it from the new file.

// src/core/http/connectToServer.ts

import config from "@mongez/config";
import router from "core/router";
import registerHttpPlugins from "./plugins";
import response from "./response";
import { getServer } from "./server";

export default async function connectToServer() {
  const server = getServer();

  registerHttpPlugins();

  // now let's add a guests route in our routes to generate a guest token to our guests.
  router.post("/guests", (_request, response) => {
    const token = server.jwt.sign({ userType: "guest" });

    return response.send({
      accessToken: token,
      userType: "guest",
    });
  });

  // now let's add an event to validate the request token
  server.addHook("onRequest", async (request, reply) => {
    if (request.url === "/guests") return;

    try {
      const user = await request.jwtVerify();

      console.log(user);
    } catch (err) {
      reply.status(401).send({
        error: "Unauthorized: Invalid Access Token",
      });
    }
  });

  // call reset method on response object to response its state
  server.addHook("onResponse", response.reset.bind(response));

  router.scan(server);

  try {
    // 👇🏻 We can use the url of the server
    const address = await server.listen({
      port: config.get("app.port"),
      host: config.get("app.baseUrl"),
    });

    console.log(`Start browsing using ${address}`);
  } catch (err) {
    console.log(err);

    server.log.error(err);
    process.exit(1); // stop the process, exit with error
  }
}
Enter fullscreen mode Exit fullscreen mode

Now our code is much better, actually it will be more better in our next article when we introduce the auth folder.

🎨 Conclusion

In this article we saw how to isolate the fastify server and its plugins, we also saw how to register plugins in the server.

🚀 Project Repository

You can find the latest updates of this project on Github

😍 Join our community

Join our community on Discord to get help and support (Node Js 2023 Channel).

🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on Youtube, the course is in Arabic language.

📚 Bonus Content 📚

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

Packages & Libraries

React Js Packages

Courses (Articles)

Top comments (0)