<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Cunningham</title>
    <description>The latest articles on DEV Community by Kevin Cunningham (@dolearning).</description>
    <link>https://dev.to/dolearning</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F35323%2Fef16f7d5-bf86-4bde-b035-08c80f62d204.jpg</url>
      <title>DEV Community: Kevin Cunningham</title>
      <link>https://dev.to/dolearning</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dolearning"/>
    <language>en</language>
    <item>
      <title>Track Errors in Fastify with AppSignal</title>
      <dc:creator>Kevin Cunningham</dc:creator>
      <pubDate>Wed, 02 Aug 2023 11:50:36 +0000</pubDate>
      <link>https://dev.to/appsignal/track-errors-in-fastify-with-appsignal-42me</link>
      <guid>https://dev.to/appsignal/track-errors-in-fastify-with-appsignal-42me</guid>
      <description>&lt;p&gt;Fastify is a cutting-edge web framework for Node.js that offers exceptional speed and efficiency. With its extensible plugin system, support for asynchronous programming, and focus on minimalism, it is an ideal choice for backend developers developing Node.js applications.&lt;/p&gt;

&lt;p&gt;But even the most performant web applications can encounter issues that are difficult to debug without the proper tools in place.&lt;/p&gt;

&lt;p&gt;We will explore how to use AppSignal for a Fastify application. By the end of this article, you'll be well-equipped to harness the potential of Fastify, using AppSignal to quickly fix bugs and identify performance bottlenecks.&lt;/p&gt;

&lt;p&gt;Let's get going!&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Fastify and AppSignal
&lt;/h2&gt;

&lt;p&gt;Before we dive into the installation, ensure you have Node installed and a code editor of your preference. Ideally, you should be running the latest LTS of Node (which is v18 at the time of writing), but if you're stuck on an earlier version, the minimum requirement is v10.&lt;/p&gt;

&lt;p&gt;In your terminal, move to a new directory, start a new project, and add Fastify as a dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my_project
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;fastify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can add the code to set up a very simple server. This has two routes, one that returns a response and one that throws an error. I've called mine &lt;code&gt;app.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fastify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fastify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is a test error.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is now listening on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be run by using Node directly with &lt;code&gt;node app.js&lt;/code&gt; or updating your &lt;code&gt;package.json&lt;/code&gt;. We'll do that in a moment, so hold off there!&lt;/p&gt;

&lt;p&gt;It's time to set up your AppSignal account. Navigate to the &lt;a href="https://www.appsignal.com/"&gt;AppSignal website&lt;/a&gt; and click on &lt;code&gt;Start free trial&lt;/code&gt;. Here, &lt;a href="https://appsignal.com/users/sign_up"&gt;you can sign up&lt;/a&gt; with a username and password or by linking AppSignal to your GitHub account. You don't need to provide any credit card details while trying out the service.&lt;/p&gt;

&lt;p&gt;Once you've signed up and logged in, you'll be brought to the dashboard. Click on the &lt;code&gt;Add app&lt;/code&gt; button on the top right, select &lt;code&gt;Node.js&lt;/code&gt;, and follow the instructions.&lt;/p&gt;

&lt;p&gt;First, we'll run &lt;code&gt;npx @appsignal/cli install&lt;/code&gt; from our project's directory. This will use the CLI tool to download and configure the AppSignal dependencies.&lt;/p&gt;

&lt;p&gt;During the installation, you'll be asked for a push api key, which you'll see listed in step 2 of the instructions. Paste that into the terminal when asked, and then name your app. Finally, save the options in a configuration file and allow the installation to finish.&lt;/p&gt;

&lt;p&gt;When it's finished installing, the CLI will print the run command to the terminal. Now we can update our &lt;code&gt;package.json&lt;/code&gt; with this line in the scripts block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node --require './appsignal.cjs' app.js"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back in the terminal, we can start up our server with AppSignal by running &lt;code&gt;npm run start&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating Fastify with AppSignal
&lt;/h2&gt;

&lt;p&gt;Excitingly, if we're going for a normal instrumentation of our Node application, we've already finished! Fastify is one of many integrations that are fully configured by the CLI tool we used above.&lt;/p&gt;

&lt;p&gt;With the Fastify integration, AppSignal receives a child span representing the execution time of each component involved during a web request. This feature provides valuable insights into the performance of individual components, helping developers identify potential bottlenecks or areas that require optimization.&lt;/p&gt;

&lt;p&gt;The integration utilizes the request route as the action name, allowing for easy identification and organization of actions within the monitoring dashboard. Moreover, query parameters and request body data are set as span attributes, offering a comprehensive view of the request details, which can prove essential in understanding the context of each action.&lt;/p&gt;

&lt;p&gt;One of the key benefits of integrating Fastify with AppSignal is automatic error tracking. This feature ensures that developers are promptly notified of any issues that arise within their application, allowing them to address problems quickly and maintain their web application's overall reliability and user experience.&lt;/p&gt;

&lt;p&gt;Let's trigger a few routes on the API we created above and explore this within AppSignal. So, either using an API client (like Postman or Insomnia) or your web browser, trigger the following routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://localhost:3000/error"&gt;http://localhost:3000/error&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://localhost:3000/not-here"&gt;http://localhost:3000/not-here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://localhost:3000/not-here?test=here"&gt;http://localhost:3000/not-here?test=here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the AppSignal dashboard page, select &lt;code&gt;Overview&lt;/code&gt; on the left-hand menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--whDWwSeW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--whDWwSeW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/dashboard.png" alt="Dashboard" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In this menu, we can decide what time period to zoom in or out to. This can help us focus on a particular time period or get a birds-eye view of how an application is performing in the long term.&lt;/li&gt;
&lt;li&gt;These three graphs draw attention to the most important metrics to monitor. Having them front and center on the dashboard allows you to keep them top of mind.&lt;/li&gt;
&lt;li&gt;Here, we have the latest open errors — we'll zoom into this in a moment.&lt;/li&gt;
&lt;li&gt;Lastly, we have the latest performance measurements. Again, we'll zoom in there soon.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Grouping Fastify Errors with AppSignal
&lt;/h2&gt;

&lt;p&gt;AppSignal does a great job of grouping errors of the same type. This stops potential issues being hidden in a live stream of data. We can also collaborate with team members to investigate issues in our application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DQtvfio5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/errors.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DQtvfio5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/errors.png" alt="Errors" width="800" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the error summary page, and a lot is going on here.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we have the HTTP method and route where this error has been triggered. All of the automated logging is identified in this way, allowing AppSignal to group the errors more reasonably.&lt;/li&gt;
&lt;li&gt;Next, we have the error message raised by the application and the end of the backtrace. This is the summary page, so we don't get a full stack trace.&lt;/li&gt;
&lt;li&gt;We can click on &lt;code&gt;Inspect latest sample&lt;/code&gt; to see a full request/response cycle for a more targeted investigation.&lt;/li&gt;
&lt;li&gt;A logbook here allows you to record what you've tried and excluded. This kind of shared notebook reduces the chances of multiple colleagues wasting time on the same approach.&lt;/li&gt;
&lt;li&gt;We can see if there is a trend for this error over the past day or 30 days.&lt;/li&gt;
&lt;li&gt;In the settings panel, we can assign this error and decide when we should alert colleagues. This is an excellent triaging mechanism, allowing teams to focus their energies on open and important issues.&lt;/li&gt;
&lt;li&gt;Lastly, any similar attributes between these requests are gathered and displayed here.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are other tabs along the top. You can explore these yourself, but I'll draw your attention to the &lt;code&gt;Samples&lt;/code&gt; tab in particular.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jfAo1be4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/samples.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jfAo1be4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/samples.png" alt="Samples" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows us to filter results based on attributes and click through for details of any requests that have triggered this error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route Performance in Fastify
&lt;/h2&gt;

&lt;p&gt;We can see that when our application throws an error, this will be tracked effectively. But what about identifying performance-based issues?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FFD3mkbO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/performance.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FFD3mkbO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/performance.png" alt="Route performance" width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the latest sample when analyzing the GET requests from our API.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We've got a clear description of the types of requests grouped together to make these samples.&lt;/li&gt;
&lt;li&gt;Here we can set the warning level. It defaults to 10 seconds. So if your API takes more than 10 seconds to respond, AppSignal will send an alert. You can lower this threshold to 200ms or raise it to around 60 minutes, depending on your needs.&lt;/li&gt;
&lt;li&gt;Here we have a description of the sample. We can see that this request results in a 404 error.&lt;/li&gt;
&lt;li&gt;Again, we've got a visual graph of trends, so we can quickly understand any potential drops or spikes in performance.&lt;/li&gt;
&lt;li&gt;We can analyze other samples to compare and contrast performance by clicking between them here.
Further down this page, we can find the attributes that describe this response and any parameters sent as part of the request URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These performance metrics are gathered based on actions. They are described by the method and the route. I'm going to set up a simple CRUD API with a MongoDB backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a CRUD API
&lt;/h2&gt;

&lt;p&gt;This tutorial assumes you have MongoDB set up on your system already. If you don't, you can head to the &lt;a href="https://www.mongodb.com/"&gt;MongoDB website&lt;/a&gt; and get yourself set up.&lt;/p&gt;

&lt;p&gt;To build the API, first add these libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @fastify/mongodb fastify-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a database connector plugin in a file called &lt;code&gt;db.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fastifyPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fastify-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fastifyMongo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@fastify/mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @param {FastifyInstance} fastify
 * @param {Object} options
 */&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;dbConnector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fastifyMongo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongodb://localhost:27017/test_database&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fastifyPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbConnector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, bring the routes into their own file, &lt;code&gt;routes.js&lt;/code&gt;, and add the routes for an animal api:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Encapsulates the routes
 * @param {FastifyInstance} fastify  Encapsulated Fastify Instance
 * @param {Object} options plugin options, refer to https://www.fastify.io/docs/latest/Reference/Plugins/#plugin-options
 */&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mongo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test_collection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is a test error.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/animals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No documents found.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/animals/:animal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/animals/:animal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleteOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deletedCount&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This item doesn't exist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;204&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animalBodyJsonSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;animal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;animalBodyJsonSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/animals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// we can use the `request.body` object to get the data sent by the client&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, back in &lt;code&gt;app.js&lt;/code&gt;, import and register the plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;fastify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since I'm importing the routes here, I've removed the &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/error&lt;/code&gt; routes I registered earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the CRUD API
&lt;/h2&gt;

&lt;p&gt;Now that these routes are set up, I can query each of them. Here's a table of the available routes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Parameters&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Returns an object containing a hello message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/error&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Throws a test error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/animals&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Returns an array of all animals in the &lt;code&gt;test_collection&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/animals/:animal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;animal&lt;/code&gt; (string, path parameter)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/animals/dog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the specific animal object from the &lt;code&gt;test_collection&lt;/code&gt; if it exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/animals/:animal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;animal&lt;/code&gt; (string, path parameter)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/animals/dog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deletes the specified animal from the &lt;code&gt;test_collection&lt;/code&gt; if it exists and returns a 204 status code, otherwise returns a 404 error with a message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/animals&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;animal&lt;/code&gt; (string, request body)&lt;/td&gt;
&lt;td&gt;Request Body: &lt;code&gt;{"animal": "dog"}&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Inserts the provided animal into the &lt;code&gt;test_collection&lt;/code&gt; and returns the result&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Back on the AppSignal Actions page, I can now see each action alongside its performance metrics:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CHmkmzE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/actions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CHmkmzE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-07/actions.png" alt="Alt text" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;As before, we can change the time range. We also have the &lt;code&gt;Custom range&lt;/code&gt;, which allows us to be forensic in our tracking.&lt;/li&gt;
&lt;li&gt;Here is the list of actions. Clicking any of these links will take us to an action's summary page. As well as linking to any errors, we can access all of the related samples that make up this data set.&lt;/li&gt;
&lt;li&gt;A quick visual of the mean time it takes for each of our actions to respond. The slowest one is &lt;code&gt;/demo&lt;/code&gt;, a sample route provided by AppSignal.&lt;/li&gt;
&lt;li&gt;The mean is a good measure. The 90th percentile tells us the speed at which 90% of our users receive a response. If these numbers are far apart, it might be worth investigating.&lt;/li&gt;
&lt;li&gt;The throughput is the total number of requests sent through the action in our chosen timeframe.&lt;/li&gt;
&lt;li&gt;The summary statistics at the bottom give us a decent summary of how our application is performing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks to our AppSignal integration, we don't need to add any custom instrumentation and can benefit from error and performance tracking straightaway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Integrating Fastify with AppSignal provides a powerful combination for developers seeking to create high-performance web applications while ensuring seamless error tracking and monitoring.&lt;/p&gt;

&lt;p&gt;Fastify's speed, efficiency, and extensibility make it an ideal choice for backend developers working with Node.js applications. Meanwhile, AppSignal's robust error tracking and performance monitoring capabilities equip developers with the insights necessary to maintain their applications' reliability and user experience.&lt;/p&gt;

&lt;p&gt;With AppSignal, you can quickly fix bugs and identify performance bottlenecks, ensuring that your application remains in top condition. It's worth exploring the capabilities and strengths of both Fastify and AppSignal further. You can also check out our &lt;a href="https://blog.appsignal.com/series/building-node.js-applications-with-fastify.html"&gt;Building Node.js Applications with Fastify series&lt;/a&gt; to learn more about Fastify.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you need an APM for your Node.js app, go and &lt;a href="https://www.appsignal.com/nodejs"&gt;check out the AppSignal APM for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>fastify</category>
      <category>node</category>
      <category>apm</category>
    </item>
    <item>
      <title>Importing SVGs to Next.js</title>
      <dc:creator>Kevin Cunningham</dc:creator>
      <pubDate>Mon, 14 Dec 2020 20:09:45 +0000</pubDate>
      <link>https://dev.to/dolearning/importing-svgs-to-next-js-nna</link>
      <guid>https://dev.to/dolearning/importing-svgs-to-next-js-nna</guid>
      <description>&lt;p&gt;SVGs are great! They are scalable vector graphics. As they are vector based they can be scaled to be huge or tiny and they won't pixelate. They are made up of XML describing the paths and shapes needed to make the final image. They are an excellent choice for responsive web design but importing them to your Next.js application isn't always straight-forward.&lt;/p&gt;

&lt;p&gt;This article will look at a few different ways to approach this common task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Including directly
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; is a standard HTML tag that can be directly used in JSX. That means if your SVG is quite short, it can be easiest to include it in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag
&lt;/h2&gt;

&lt;p&gt;You can use a regular img tag and reference the SVG by URL. You need to place the image in the &lt;code&gt;/public&lt;/code&gt; directory and reference it relative to that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/eye.svg"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"An SVG of an eye"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file would be in the root of the &lt;code&gt;public&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use next/image
&lt;/h2&gt;

&lt;p&gt;Equally, you could use the &lt;code&gt;Image&lt;/code&gt; component that is included in &lt;code&gt;next/image&lt;/code&gt;. The only thing to be aware here is that this component requires the height and width to be passed through as props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/eye.svg"&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  As a component
&lt;/h2&gt;

&lt;p&gt;You can include it as component in your document and call it as you need. This has the benefit of keeping the SVG code in one place.&lt;/p&gt;

&lt;p&gt;It isn't much further from this to have this SVG as a component in a separate file.&lt;/p&gt;

&lt;p&gt;Once you have your SVG as a component, you can pass it props to alter it's appearance. You receive the props and then use them directly on your SVG.&lt;/p&gt;

&lt;h1&gt;
  
  
  Importing as a file
&lt;/h1&gt;

&lt;p&gt;If you try to import an SVG directly as a file like this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;eye&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../assets/eye.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will get an error that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Module parse failed: Unexpected token (1:2)
 You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be able to make this work, you'll need to either add a webpack or babel extension.&lt;/p&gt;

&lt;p&gt;Let's look at a webpack solution first.&lt;/p&gt;

&lt;h2&gt;
  
  
  SVGR
&lt;/h2&gt;

&lt;p&gt;This tool comes built in with create-react-app, so if you've used that before then this will be a familiar tool.&lt;/p&gt;

&lt;p&gt;First, use yarn or npm to install &lt;code&gt;@svgr/webpack&lt;/code&gt; to your project. You'll then need to create or add to your &lt;code&gt;next.config.js&lt;/code&gt; in the root of your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;webpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;svg$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@svgr/webpack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Webpack can sometimes be a little bit incomprehensible to me. Here we are adding a rule (&lt;code&gt;rules.push&lt;/code&gt;). Specifically, we test if the file is an SVG and, if it is, we use the library we installed above.&lt;/p&gt;

&lt;p&gt;It's worth noting that if you make changes to your &lt;code&gt;next.config.js&lt;/code&gt; you'll need to restart the development server before you'll notice the changes.&lt;/p&gt;

&lt;p&gt;Once restarted, the error above should be gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  babel plugin
&lt;/h2&gt;

&lt;p&gt;If you'd rather not hook into webpack, you can use babel instead. There is a plugin called &lt;code&gt;babel-plugin-inline-react-svg&lt;/code&gt;. Install the library and then create a &lt;code&gt;.babelrc&lt;/code&gt; in the root of your repo.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.babelrc&lt;/code&gt; is an object that has two keys, presets and plugins. In presets, we are going to add &lt;code&gt;next/babel&lt;/code&gt;. This is included in the project anyway but by adding a configuration file we need to specify it explicitly.&lt;/p&gt;

&lt;p&gt;For our plugins, we are going to add &lt;code&gt;inline-react-svg&lt;/code&gt;. So, the final file will look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;presets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/babel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plugins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline-react-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  next-images
&lt;/h2&gt;

&lt;p&gt;If you'd rather have one solution that covers a number of different image types, then &lt;code&gt;next-images&lt;/code&gt; is a library that might be of interest. This is a plugin optimised for Next.js and allows for a &lt;code&gt;svg&lt;/code&gt;, &lt;code&gt;ico&lt;/code&gt;, &lt;code&gt;jp2&lt;/code&gt; and other types of images to be imported into your projecct.&lt;/p&gt;

&lt;p&gt;Once the dependency has been installed, this one needs a &lt;code&gt;next.config.js&lt;/code&gt; configuration as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next-images&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withImages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Which one should you use?
&lt;/h1&gt;

&lt;p&gt;I'm not the boss of you :)&lt;/p&gt;

&lt;p&gt;I have a decision tree that looks a bit like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I want control over the SVG?

&lt;ul&gt;
&lt;li&gt;Component with props&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Is it an image that is going to be content managed?

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;next-images&lt;/code&gt; or webpack&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Is it an image I'm only going to use once?

&lt;ul&gt;
&lt;li&gt;Stick it in the &lt;code&gt;public&lt;/code&gt; direct and reference it directly&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How about you? Which approach do you prefer and why?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/s/next-import-svg-8rip3"&gt;Here's a Codesandbox&lt;/a&gt; with all of the various options we've discussed in this post.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://twitter.com/dolearning"&gt;Come follow me on Twitter&lt;/a&gt;. I share helpful tips and fun things I find on the web.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>svg</category>
    </item>
    <item>
      <title>Why does your frontend application need a server?</title>
      <dc:creator>Kevin Cunningham</dc:creator>
      <pubDate>Thu, 08 Oct 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dolearning/why-does-your-frontend-application-need-a-server-2hfk</link>
      <guid>https://dev.to/dolearning/why-does-your-frontend-application-need-a-server-2hfk</guid>
      <description>&lt;p&gt;I started my development career working with monolithic frameworks like Django (in Python) and Drupal (in PHP). Now, I'm paid almost entirely to build React applications. It was strange for me when I started this journey to properly understand that React only deals with part of building an application. I wonder if you've considered this before?&lt;/p&gt;

&lt;h2&gt;
  
  
  Deliberately unopinionated
&lt;/h2&gt;

&lt;p&gt;Even though some habits and practices have grown up around data fetching, persistence and state management there is no "official" best way to handle these.&lt;/p&gt;

&lt;p&gt;The Python community value having the one "Pythonic" way to solve any given problem. The Ruby community values the ability to solve the same problem in myriad different ways. Each language and community has different approaches.&lt;/p&gt;

&lt;p&gt;With React there are clear opinions about how things are handled in the browser - re-rendering, hook rules, error boundaries - but that leaves the back-end more freeform. Everything about how data arrives in React is left to the discretion of the individual teams of developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do we need our own servers?
&lt;/h2&gt;

&lt;p&gt;Say you are building something like the &lt;a href="https://coronavirus.jhu.edu/map.html"&gt;Johns Hopkins Covid Dashboard&lt;/a&gt;. This relies on the fetching and processing of a lot of varying data points&lt;/p&gt;

&lt;p&gt;If you don't have a server, your application is going to need to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;query the data (possibly from multiple sources)&lt;/li&gt;
&lt;li&gt;parse the data (make it readable, exclude unnecessary information, get it into the right form, carry out any calculations)&lt;/li&gt;
&lt;li&gt;possibly cache the data (to stop fetching too much information)&lt;/li&gt;
&lt;li&gt;render the data (make things look understandable and helpful)&lt;/li&gt;
&lt;li&gt;update the displayed data based on user interactions (selections, movements, etc)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see that this would take a lot of time and put a lot of pressure on the browsers of your users. With a custom server, you gather all the data in one spot, have it in the right shape and cache it for your visitors.&lt;/p&gt;

&lt;p&gt;This means React can do what it does best, render the data and update the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is that the only reason?
&lt;/h2&gt;

&lt;p&gt;There are other big reasons that servers are important for your applications.&lt;/p&gt;

&lt;p&gt;First, there is the need to persist data through sessions. Without interacting with a server, any updates to the data in a browser will be lost after refresh. We could use cookies and localStorage to have some short-term persistence but these would not survive a cache clear, for example.&lt;/p&gt;

&lt;p&gt;Second (and maybe this should have been first), security. If Johns Hopkins is relying on proprietary information, they would have an API key that uniquely identifies them to the vendor. If their application queried this data from the browser that API key would need to be shared and therefore could be found by the users. Having a server means the API key is safe, the proprietary data is only ever accessed by the server. The relevant data is built into the correct shape and passed back to the frontend with no knowledge where it started.&lt;/p&gt;

&lt;p&gt;Thirdly, any costly calculations can be carried out on the server and the answers passed back to the client. This makes the experience of the end-user more smooth and responsive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you build your server with?
&lt;/h2&gt;

&lt;p&gt;There are so many options here! You could use Node.js and Express - a favourite of JavaScript developers. You could build your backend in Rust, PHP, Python, Clojure or any other language that can run a webserver.&lt;/p&gt;

&lt;p&gt;Frameworks like Next.js are trying to help with this overload. Next allows the creation of API routes in their applications. Once the applications are deployed to Vercel or Netlify, this routes are transformed into individual serverless functions. This reduces the development and deployment costs, as well as decision fatigue.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Why else do you think we use servers?&lt;/li&gt;
&lt;li&gt;What other good ways do you use to build servers?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Follow me on &lt;a href="https://twitter.com/dolearning"&gt;Twitter&lt;/a&gt; if you've found this helpful.&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>api</category>
    </item>
  </channel>
</rss>
