<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://savory.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://savory.github.io/" rel="alternate" type="text/html" /><updated>2022-10-21T12:07:44+00:00</updated><id>https://savory.github.io/feed.xml</id><title type="html">Savory</title><subtitle>All news about our ecosystem</subtitle><author><name>Thomas Cruveilher</name></author><entry><title type="html">Use Mongodb in Deno with Danet</title><link href="https://savory.github.io/mongodb-in-danet/" rel="alternate" type="text/html" title="Use Mongodb in Deno with Danet" /><published>2022-10-16T00:00:00+00:00</published><updated>2022-10-16T00:00:00+00:00</updated><id>https://savory.github.io/mongodb-in-danet</id><content type="html" xml:base="https://savory.github.io/mongodb-in-danet/">&lt;p&gt;&lt;img src=&quot;/assets/images/deno logo.png&quot; alt=&quot;deno logo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Welcome ! Today’s article is here to help you add a MongoDB connection to your Danet’s API.&lt;/p&gt;

&lt;p&gt;We assume that you already have a MongoDB database available, either locally (&lt;a href=&quot;https://www.mongodb.com/docs/manual/installation/&quot;&gt;documentation here&lt;/a&gt;) or on a remote server/cloud provider, such as &lt;a href=&quot;https://www.mongodb.com/atlas/database?tck=docs_server&quot;&gt;MongoDB Atlas&lt;/a&gt; which has an awesome free tier.&lt;/p&gt;

&lt;p&gt;To connect to our mongodb database we will use the Denodrivers’ mongo driver  : &lt;a href=&quot;https://deno.land/x/mongo@v0.31.1&quot;&gt;https://deno.land/x/mongo@v0.31.1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In most cases, the database’s connection is shared among all our services in our code, our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MongoDBService&lt;/code&gt; will then be a Singleton.&lt;/p&gt;

&lt;p&gt;We also need to connect to our Database Server only once, when the app starts, and we need to close the connection when our app stops. In order to do this, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onAppBootstrap&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onAppShutdown&lt;/code&gt; lifecycle hooks !&lt;/p&gt;

&lt;p&gt;Let’s dive into the code now :&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/18d9871cf4f61f22e7e168b701b70b4d.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;For simplicity’s sake, we are importing everything from urls. However, we recommend creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deps.ts&lt;/code&gt; file to import/export everything. Doing so result in a single point of truth and an easier maintenance.&lt;/p&gt;

&lt;p&gt;Few key points  :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The service implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnAppBoostrap&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnAppShutdown&lt;/code&gt; to use lifecycle hooks.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The connection URI is created using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Deno.env.get&lt;/code&gt; to get environment variables.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, we need to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DatabaseModule&lt;/code&gt; to keep our code clean :&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/2d2b7ec77bfdc404304010802cd326e7.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Import this module in any module that need your newly created &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MongoDBService&lt;/code&gt;, and use it wherever you need.&lt;/p&gt;

&lt;p&gt;Here is a simplified code from of our &lt;a href=&quot;https://github.com/Savory/Danet-Starter&quot;&gt;Starter Repository&lt;/a&gt; that contains all the necessary code to work with MongoDB AND Postgres seamlessly:&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MongodbRepository&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MongoDBService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;findOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ObjectId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Omit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insertedId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Omit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insertOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insertedId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;objectId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ObjectId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;objectId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;$set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;deleteOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;deleteOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ObjectId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;deleteAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;deleteMany&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Well, that’s it folks ! It wasn’t hard, now you know !&lt;/p&gt;

&lt;p&gt;To learn how to use Postgres in Danet, check &lt;a href=&quot;/postgres-in-danet/&quot;&gt;this article out&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To learn more about Danet, check out our documentation : &lt;a href=&quot;https://savory.github.io/Danet/&quot;&gt;https://savory.github.io/Danet/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The GitHub repository if you want to contribute : &lt;a href=&quot;https://github.com/Savory/Danet&quot;&gt;https://github.com/Savory/Danet&lt;/a&gt;&lt;/p&gt;</content><author><name>Thomas Cruveilher</name></author><summary type="html">Get ready to use MongoDB in Danet in few minutes !</summary></entry><entry><title type="html">Use Postgres in Deno with Danet</title><link href="https://savory.github.io/postgres-in-danet/" rel="alternate" type="text/html" title="Use Postgres in Deno with Danet" /><published>2022-10-16T00:00:00+00:00</published><updated>2022-10-16T00:00:00+00:00</updated><id>https://savory.github.io/postgres-in-danet</id><content type="html" xml:base="https://savory.github.io/postgres-in-danet/">&lt;p&gt;&lt;img src=&quot;/assets/images/deno logo.png&quot; alt=&quot;deno logo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Welcome ! Today’s article is here to help you add a Postgres connection to your Danet’s API.&lt;/p&gt;

&lt;p&gt;We assume that you already have a MongoDB database available, either locally (&lt;a href=&quot;https://www.mongodb.com/docs/manual/installation/&quot;&gt;documentation here&lt;/a&gt;) or on a remote server/cloud provider, such as &lt;a href=&quot;https://www.mongodb.com/atlas/database?tck=docs_server&quot;&gt;MongoDB Atlas&lt;/a&gt; which has an awesome free tier.&lt;/p&gt;

&lt;p&gt;To connect to our postgres database we will use the Denodrivers’ mongo driver  : &lt;a href=&quot;https://deno.land/x/postgres&quot;&gt;https://deno.land/x/postgres&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In most cases, the database’s connection is shared among all our services in our code, our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PostgresService&lt;/code&gt; will then be a Singleton.&lt;/p&gt;

&lt;p&gt;We also need to connect to our Database Server only once, when the app starts, and we need to close the connection when our app stops. In order to do this, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onAppBootstrap&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onAppShutdown&lt;/code&gt; lifecycle hooks !&lt;/p&gt;

&lt;p&gt;Let’s dive into the code now :&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/13bc7ab4b90f39eeff60cff54f7d6f2b.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;For simplicity’s sake, we are importing everything from urls. However, we recommend creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deps.ts&lt;/code&gt; file to import/export everything. Doing so result in a single point of truth and an easier maintenance.&lt;/p&gt;

&lt;p&gt;Few key points  :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The service implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnAppBoostrap&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnAppShutdown&lt;/code&gt; to use lifecycle hooks.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The connection URI is created using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Deno.env.get&lt;/code&gt; to get environment variables.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, we need to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DatabaseModule&lt;/code&gt; to keep our code clean :&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/525636dab7fe70de009425b640a85814.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Import this module in any module that need your newly created &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PostgresService&lt;/code&gt;, and use it wherever you need.&lt;/p&gt;

&lt;p&gt;Here is a simplified code from of our &lt;a href=&quot;https://github.com/Savory/Danet-Starter&quot;&gt;Starter Repository&lt;/a&gt; that contains all the necessary code to work with Postgres AND MongoDb seamlessly:&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PostgresService&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;../database/postgresService.ts&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PostgresRepository&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PostgresService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queryObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`SELECT * FROM TODO`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queryObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;`SELECT _id, title, content FROM TODO WHERE _id = '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;'`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Omit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queryObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;`INSERT INTO TODO (title, content) VALUES ('&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;', '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;') RETURNING _id, title, content;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queryObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;`UPDATE TODO SET title = '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;', content = '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;' WHERE _id = '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;' RETURNING _id, title, content;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;deleteOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queryObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;`DELETE FROM TODO WHERE _id = '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todoId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;';`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;deleteAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dbService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queryObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`DELETE FROM TODO`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Well, that’s it folks ! It wasn’t hard, now you know !&lt;/p&gt;

&lt;p&gt;To learn how to use MongoDB in Danet, check &lt;a href=&quot;/mongodb-in-danet/&quot;&gt;this article out&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To learn more about Danet, check out our documentation : &lt;a href=&quot;https://savory.github.io/Danet/&quot;&gt;https://savory.github.io/Danet/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The GitHub repository if you want to contribute : &lt;a href=&quot;https://github.com/Savory/Danet&quot;&gt;https://github.com/Savory/Danet&lt;/a&gt;&lt;/p&gt;</content><author><name>Thomas Cruveilher</name></author><summary type="html">Get ready to use Postgres in Danet in few minutes !</summary></entry><entry><title type="html">Body validation in Danet</title><link href="https://savory.github.io/body-validation-in-danet/" rel="alternate" type="text/html" title="Body validation in Danet" /><published>2022-10-07T00:00:00+00:00</published><updated>2022-10-07T00:00:00+00:00</updated><id>https://savory.github.io/body-validation-in-danet</id><content type="html" xml:base="https://savory.github.io/body-validation-in-danet/">&lt;p&gt;&lt;img src=&quot;/assets/images/deno logo.png&quot; alt=&quot;deno logo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Welcome ! Last time, we saw &lt;a href=&quot;/how-to-build-an-api-in-deno-with-danet/&quot;&gt;how to create a REST API in Deno using Danet&lt;/a&gt;. Today, we will add Body validation to it.&lt;/p&gt;

&lt;p&gt;In order to do that simply add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Decorators&lt;/code&gt; from &lt;a href=&quot;https://github.com/Savory/validatte&quot;&gt;our validatte package&lt;/a&gt; to your classes !&lt;/p&gt;

&lt;p&gt;Let’s look at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo.controller.ts&lt;/code&gt; :&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/2ccdbfce179625283cc206c1057d22c9.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;As we can see, we indicate that to create Todo, we need to do a POST request and send a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Todo&lt;/code&gt;-ish object in the body. We get this object by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Body&lt;/code&gt; decorator.&lt;/p&gt;

&lt;p&gt;However, the body format is not validated anywhere. Let’s say we decided that a description should not be less than 20 characters. With the current code, I would be able to send the following body:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tooshort&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;title&lt;/code&gt; is not a string and that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content&lt;/code&gt;’s length is lower than 20 characters.&lt;/p&gt;

&lt;p&gt;To enforce our body format, we simply need to slightly change our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo.class.ts&lt;/code&gt; as following :&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/6bd47c3a721a1e2adb17eb9fc98fb006.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;By adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@IsString()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@LengthGreater(20)&lt;/code&gt;, we are attaching validators.&lt;/p&gt;

&lt;p&gt;Under the hood, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Body&lt;/code&gt; decorator get the expected body type, and check if there is any validators attached to the class attributes.
If there is, it calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validateObject()&lt;/code&gt; function from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validatte&lt;/code&gt; against the body.
If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validateObject&lt;/code&gt; returns errors, an HTTP 400 BadRequest is thrown with explicit errors :&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;reasons&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;property&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;errorMessage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Length must be greater than 20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;constraints&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Well, that’s it folks ! It wasn’t hard, now you know !&lt;/p&gt;

&lt;p&gt;To learn more about Danet, check out our documentation : &lt;a href=&quot;https://savory.github.io/Danet/&quot;&gt;https://savory.github.io/Danet/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the GitHub repository if you want to contribute : &lt;a href=&quot;https://github.com/Savory/Danet&quot;&gt;https://github.com/Savory/Danet&lt;/a&gt;&lt;/p&gt;</content><author><name>Thomas Cruveilher</name></author><summary type="html">Welcome ! Last time, we saw [how to create a REST API in Deno using Danet]({{site.baseurl}}{% post_url 2022-08-28-how-to-build-an-api-in-deno-with-danet %}). Today, we will add Body validation to it.</summary></entry><entry><title type="html">How to build an API in Deno with Danet</title><link href="https://savory.github.io/how-to-build-an-api-in-deno-with-danet/" rel="alternate" type="text/html" title="How to build an API in Deno with Danet" /><published>2022-08-28T00:00:00+00:00</published><updated>2022-08-28T00:00:00+00:00</updated><id>https://savory.github.io/how-to-build-an-api-in-deno-with-danet</id><content type="html" xml:base="https://savory.github.io/how-to-build-an-api-in-deno-with-danet/">&lt;p&gt;Welcome, take a seat, and keep your keyboard at hand because today we are building a REST API in Deno using Danet. In the end, we’ll also show you how to handle authentication.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/deno logo.png&quot; alt=&quot;deno logo.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;what-is-deno&quot;&gt;What is Deno ?&lt;/h2&gt;
&lt;p&gt;Deno is a simple, modern, and secure runtime for JavaScript, TypeScript, and WebAssembly that uses V8 and is built in Rust.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Provides web platform functionality and adopts web platform standards.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Secure by default. No file, network, or environment access, unless explicitly enabled.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Supports TypeScript out of the box.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ships only a single executable file.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Has built-in development tooling like a dependency inspector (deno info) and a code formatter (deno fmt).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can learn more here on Deno’s official website &lt;a href=&quot;https://deno.land/&quot;&gt;https://deno.land/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;what-is-danet&quot;&gt;What is Danet ?&lt;/h2&gt;

&lt;p&gt;Danet is a new open-source framework. Nest was one of the greatest tools to improve architecture of NodeJS project. Danet wants to bring the same level of pro-efficiency and professionalism into Deno’s world.&lt;/p&gt;

&lt;p&gt;Exactly like Nest, Danet provides an out-of-the-box application architecture that allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications.&lt;/p&gt;

&lt;p&gt;It is entirely made in Typescript.&lt;/p&gt;

&lt;p&gt;You can find the documentation here : &lt;a href=&quot;https://savory.github.io/Danet/&quot;&gt;https://savory.github.io/Danet/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the GitHub repository : &lt;a href=&quot;https://github.com/Savory/Danet&quot;&gt;https://github.com/Savory/Danet&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;First thing first, we need to have Deno ≥ v1.24.3&lt;/p&gt;

&lt;h3 id=&quot;deno-updated-on-27th-august2022&quot;&gt;Deno (updated on 27th August 2022)&lt;/h3&gt;

&lt;p&gt;Deno ships as a single executable with no dependencies. You can install it using the installers below, or download a release binary from the releases page.&lt;/p&gt;

&lt;h4 id=&quot;shell-mac-linux&quot;&gt;Shell (Mac, Linux):&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl -fsSL https://deno.land/install.sh | sh&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;powershell-windows&quot;&gt;PowerShell (Windows):&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;irm https:deno.land/install.ps1 | iex&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&quot;homebrew-mac&quot;&gt;Homebrew (Mac):&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew install deno&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;https://github.com/denoland/deno_install&quot;&gt;deno_install&lt;/a&gt; for more installation options.&lt;/p&gt;

&lt;h3 id=&quot;danet&quot;&gt;Danet&lt;/h3&gt;

&lt;p&gt;The easiest way to start a Danet’s project is to clone the starter project from the following GitHub repository:&lt;a href=&quot;https://github.com/Savory/Danet-Starter&quot;&gt;https://github.com/Savory/Danet-Starter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone git@github.com:Savory/Danet-Starter.git&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;basic-tutorial&quot;&gt;Basic tutorial&lt;/h2&gt;

&lt;p&gt;The starter project is a simple in-memory REST API for a to-do list.&lt;/p&gt;

&lt;p&gt;Here is how the project looks:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/deno-start-tree.png&quot; alt=&quot;deno-start-tree.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We will go through each file’s content except for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LICENSE&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo.test.ts&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;srcdepsts&quot;&gt;src/deps.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/d3b0c98252b17744942757abdbfcff3c.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;In Deno, it’s best to provide our dependency version number in our code, as there is no external file that lists our dependencies.&lt;/p&gt;

&lt;p&gt;This file export our third-party dependencies. In our code, when we will need something from danet , we will import it from deps.ts .&lt;/p&gt;

&lt;p&gt;If we ever need to upgrade a dependency, we change the version number in deps.ts .&lt;/p&gt;

&lt;h3 id=&quot;srctodoclassts&quot;&gt;src/todo/class.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/1422e15c4934872cbfb841e484241a47.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Simplest file, we define our Todo class.&lt;/p&gt;

&lt;h3 id=&quot;srctodocontrollerts&quot;&gt;src/todo/controller.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/2ccdbfce179625283cc206c1057d22c9.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Controllers are responsible for handling incoming &lt;strong&gt;requests&lt;/strong&gt; and returning &lt;strong&gt;responses&lt;/strong&gt; to the client.&lt;/p&gt;

&lt;p&gt;A controller’s purpose is to receive specific requests for the application. The &lt;strong&gt;routing&lt;/strong&gt; mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.&lt;/p&gt;

&lt;p&gt;In order to create a basic controller, we use classes and &lt;strong&gt;decorators&lt;/strong&gt;. Decorators associate classes with required metadata and enable Danet to create a routing map (tie requests to the corresponding controllers).&lt;/p&gt;

&lt;p&gt;We use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Controller()&lt;/code&gt; decorator, which is &lt;strong&gt;required&lt;/strong&gt; to define a basic controller. We’ll specify an optional route path prefix of todo. Using a path prefix in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Controller()&lt;/code&gt; decorator allows us to easily group a set of related routes, and minimize repetitive code. For example, we may choose to group a set of routes that manage interactions with a customer entity under the route /customers. In that case, we could specify the path prefix customers in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Controller()&lt;/code&gt; decorator so that we don’t have to repeat that portion of the path for each route in the file.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constructor(public todoService: TodoService)&lt;/code&gt; uses &lt;strong&gt;Dependency Injection&lt;/strong&gt;. Danet is built around this strong design pattern. We recommend reading a great article about this concept in the &lt;a href=&quot;https://angular.io/guide/dependency-injection&quot;&gt;official Angular documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;srctodoservicets&quot;&gt;src/todo/service.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/b85e0fd8bbec4c8fb58156b1ce522de1.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;This service, which is automatically injected into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoController&lt;/code&gt; thanks to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Injectabledecorator&lt;/code&gt;, contains all our business logic.
For simplicity’s sake, it only stores Todos in memory. However, for your real projects, storage should be handled by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todoRepository&lt;/code&gt; class injected into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoService&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;srctodomodulets&quot;&gt;src/todo/module.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/4338ca7300d6ef5935aead33a474c578.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;A module is a class annotated with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Module()&lt;/code&gt; decorator. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Module()&lt;/code&gt; decorator provides metadata that &lt;strong&gt;Danet&lt;/strong&gt; makes use of to organize the application structure.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Module()&lt;/code&gt; decorator takes a single object whose properties describe the module:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;injectables&lt;/code&gt; the injectables that will be instantiated by the Danet injector and that may be shared at least across this module&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;controllers&lt;/code&gt; the set of controllers defined in this module which have to be instantiated&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;imports&lt;/code&gt; the list of imported modules that declare the injectables which are required in this module&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our application being fairly simple, we only have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoController&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoService&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;srcappmodulets&quot;&gt;src/app.module.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/e411daa9b33253efd5af0115a431e12b.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;The AppModule import all modules you want your application to use. In our case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoModule&lt;/code&gt; is sufficient.&lt;/p&gt;

&lt;h3 id=&quot;srcbootstrapts&quot;&gt;src/bootstrap.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/06131f71a011942a3243e5125f56438e.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;The bootstrapfunction create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DanetApplication&lt;/code&gt; instance and initialize it with our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppModule&lt;/code&gt; . Behind the scene, it resolves and injects dependencies; creates route handle etc….&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This does not make the http server listen to any port yet.&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;runts&quot;&gt;run.ts&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/b1230abb98fd836f35075e1c354a91dc.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;It is the entry point of our app. This file is executed by Deno when we execute the launch-server task defined in deno.json .&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootstrap&lt;/code&gt; function create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DanetApplication&lt;/code&gt; instance, and we call listen method to listen (not very explicit I know /s) on a given port either from env or default to 3000 (no specific reason).&lt;/p&gt;

&lt;h3 id=&quot;denojson&quot;&gt;deno.json&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/674324699d1a5f09908660ec5d521aef.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Deno’s configuration file.&lt;/p&gt;

&lt;p&gt;It defines 2 tasks, launch-server and test , which means that you can execute deno task launch-server to run the server, and deno task test to run tests that are in the spec folder.&lt;/p&gt;

&lt;p&gt;Let’s take a second to talk about Deno’s arguments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow-net allow&lt;/code&gt; network access. You can specify an optional, comma-separated list of IP addresses or hostnames (optionally with ports) to provide an allow-list of allowed network addresses.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow-env&lt;/code&gt;  Allow environment access for things like getting and setting environment variables. Since Deno 1.9, you can specify an optional, comma-separated list of environment variables to provide an allow-list of allowed environment variables.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow-read&lt;/code&gt; for file system read access. You can specify an optional, comma-separated list of directories or files to provide an allow-list of allowed file system access.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full documentation is accessible here : &lt;a href=&quot;https://deno.land/manual@v1.25.0/getting_started/permissions#permissions-list&quot;&gt;https://deno.land/manual@v1.25.0/getting_started/permissions#permissions-list&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it. With all the provided code (taken from Danet Starter Repository), you should have a REST API up and running !&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;But Thomas, you told us we were going to see how to handle Authentication with Danet !&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You are right pal, let’s talk about &lt;/p&gt;

&lt;h2 id=&quot;guards&quot;&gt;Guards&lt;/h2&gt;

&lt;p&gt;A guard is a class annotated with the @Injectable() decorator, which implements the AuthGuard interface.&lt;/p&gt;

&lt;p&gt;Guards have a &lt;strong&gt;single responsibility&lt;/strong&gt;. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as &lt;strong&gt;authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is an over simplified example of a guard : &lt;/p&gt;

&lt;p&gt;The logic inside the validateRequest() function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.&lt;/p&gt;

&lt;p&gt;Every guard must implement a canActivate() function. This function should &lt;strong&gt;return a boolean&lt;/strong&gt;, indicating whether the current request is allowed or not. It can return the response either synchronously or asynchronously via a Promise.&lt;/p&gt;

&lt;p&gt;Danet uses the return value to control the next action:
if it returns true, the request will be processed.
if it returns false, Danet will deny the request.&lt;/p&gt;

&lt;p&gt;Guards can be attached to a &lt;strong&gt;Controller&lt;/strong&gt;, a &lt;strong&gt;Method/Route&lt;/strong&gt;, or even registered as global guards (that will be used for &lt;strong&gt;EVERY ROUTE&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;To attach it to our TodoController we just need to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@UseGuardsdecorator&lt;/code&gt; as following:&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;Controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;UseGuards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SimpleGuard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TodoController&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;....&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can set up a global guard by providing it to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppModule&lt;/code&gt; the following way :&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthGuard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;GLOBAL_GUARD&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://deno.land/x/danet/mod.ts&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;providers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TokenInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SimpleGuard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;GLOBAL_GUARD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it folks !&lt;/p&gt;</content><author><name>Thomas Cruveilher</name></author><summary type="html">Welcome, take a seat, and keep your keyboard at hand because today we are building a REST API in Deno using Danet. In the end, we’ll also show you how to handle authentication.</summary></entry></feed>