<?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: Aviad Shikloshi</title>
    <description>The latest articles on DEV Community by Aviad Shikloshi (@shikloshi).</description>
    <link>https://dev.to/shikloshi</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%2F116631%2Fa826dac1-8ced-46e3-9d77-4a2a5cef0e07.jpeg</url>
      <title>DEV Community: Aviad Shikloshi</title>
      <link>https://dev.to/shikloshi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shikloshi"/>
    <language>en</language>
    <item>
      <title>One Hour with Deno</title>
      <dc:creator>Aviad Shikloshi</dc:creator>
      <pubDate>Sat, 07 May 2022 15:35:07 +0000</pubDate>
      <link>https://dev.to/shikloshi/one-hour-with-deno-1k75</link>
      <guid>https://dev.to/shikloshi/one-hour-with-deno-1k75</guid>
      <description>&lt;p&gt;Part of my Saturday morning routine is to explore a new technology I find interesting. It's limited to one hour so that I won't drift away and stay focused.&lt;/p&gt;

&lt;p&gt;Usually it begins with a simple "Hello, World" to setup my environment, and continues on to discover some basics around the eco system. &lt;/p&gt;

&lt;p&gt;If it's a new runtime or a programming language, I will try to setup something a bit more realistic than the &lt;code&gt;hello-world&lt;/code&gt; example - REST API most of the time will do the trick.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hello, Deno!
&lt;/h3&gt;

&lt;blockquote&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;br&gt;
from &lt;a href="https://deno.land/"&gt;Official website&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It was created by &lt;a href="https://en.wikipedia.org/wiki/Ryan_Dahl"&gt;Ryan Dahl&lt;/a&gt; who also authored &lt;code&gt;Node.js&lt;/code&gt; and while it's not suppose to be a replacement, it does try to fix some of &lt;code&gt;Node.js&lt;/code&gt; disadvantages. &lt;/p&gt;

&lt;p&gt;Let's start! For mac users all you need to do is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ brew &lt;span class="nb"&gt;install &lt;/span&gt;deno
❯ &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"console.log('Hello, Deno!')"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  hello.ts
❯ deno run hello.ts
Check file:///Users/shikloshi/projects/deno/hello.ts
Hello, Deno!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a working &lt;code&gt;Deno&lt;/code&gt; application.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about NPM and &lt;code&gt;node_modules&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Deno&lt;/code&gt; was first introduced in order to fix a lot of the things going on with &lt;code&gt;Node.js&lt;/code&gt; eco system that &lt;a href="https://en.wikipedia.org/wiki/Ryan_Dahl"&gt;Ryan Dahl&lt;/a&gt; was not a fan of.&lt;/p&gt;

&lt;p&gt;Package management and &lt;code&gt;npm&lt;/code&gt; was always kind of controversial topics in &lt;code&gt;Node.js&lt;/code&gt; community but either way, we did learned a lot from this approach. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Deno&lt;/code&gt; there is no real package manager for now, and no &lt;code&gt;node_modules&lt;/code&gt; directory that holds all your project dependencies.&lt;/p&gt;

&lt;p&gt;If you want to use &lt;code&gt;Deno&lt;/code&gt; third party libraries you can do it via Remote Imports.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ This is a very wide and interesting topic that I would probably invest time in understanding deeply in the future. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will start using &lt;a href="https://deno.land/x/destjs@v0.2.0"&gt;&lt;code&gt;destjs&lt;/code&gt;&lt;/a&gt; soon so let's import it to our &lt;code&gt;main.ts&lt;/code&gt; file and create our app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt; &lt;span class="p"&gt;}&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;https://deno.land/x/destjs@v0.1.2/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// This is a remote import - NEAT&lt;/span&gt;

&lt;span class="nx"&gt;createApp&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;8000&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now - &lt;code&gt;createApp&lt;/code&gt; - simply initalize our app with our controllers and expose endpoints via &lt;code&gt;oak&lt;/code&gt; http server.&lt;br&gt;
When running this, we can access our app via &lt;code&gt;localhost:8000&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ If you are not familiar with &lt;code&gt;NestJS&lt;/code&gt; - I would say that the library expects files to be located in a specific directory tree (a type of &lt;a href="https://en.wikipedia.org/wiki/Convention_over_configuration"&gt;convention over configuration&lt;/a&gt;). For instance: any exported class from controllers directory, with the compelling decorators, gets registered as a server endpoint. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's create our first application controller. Simply put, controller is where our HTTP endpoints are being defined and where we call any business logic related to this endpoint. &lt;/p&gt;

&lt;p&gt;We will call our first controller &lt;code&gt;controller/plant.controller.ts&lt;/code&gt; and for now it will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="p"&gt;}&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;https://deno.land/x/destjs@v0.2.0/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpContext&lt;/span&gt; &lt;span class="p"&gt;}&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;https://deno.land/x/destjs@v0.2.0/types.ts&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="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/plants&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PlantsController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&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="c1"&gt;// (2) &lt;/span&gt;
  &lt;span class="nx"&gt;getOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpContext&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="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&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;plant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monstera&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;beautiful&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we call this controller endpoint &lt;code&gt;http://localhost:8000/plants&lt;/code&gt; with a HTTP GET request, we get in response a beautiful Monstera. Later on we will use a database to store our plants and do some operations on it.&lt;/p&gt;

&lt;h5&gt;
  
  
  Let's zoom in on a few things:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;(1) &lt;code&gt;@Controller('/plants')&lt;/code&gt; decorator - For now, what we need to know about it is that it create a family of HTTP endpoints that is accessible in our application. Here we can see &lt;code&gt;/plants&lt;/code&gt; endpoint. &lt;/li&gt;
&lt;li&gt;(2) &lt;code&gt;@Get('/')&lt;/code&gt; decorator for fetching a plant with HTTP GET request to &lt;code&gt;/plants&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;(3) Remote Import for our library.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a standart &lt;code&gt;NestJS&lt;/code&gt; way of minimzing a lot of the boilerplate we used to have with &lt;code&gt;Express.js&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  Troubleshoot library issues
&lt;/h4&gt;

&lt;p&gt;This is where it was suppose to run, but an error occurs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-read&lt;/span&gt; ./main.ts
error: Uncaught &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;in &lt;/span&gt;promise&lt;span class="o"&gt;)&lt;/span&gt; NotFound: No such file or directory &lt;span class="o"&gt;(&lt;/span&gt;os error 2&lt;span class="o"&gt;)&lt;/span&gt;, readdir &lt;span class="s1"&gt;'middlewares'&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;await &lt;span class="o"&gt;(&lt;/span&gt;const item of Deno.readDir&lt;span class="o"&gt;(&lt;/span&gt;name&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                   ^
    at async Object.[Symbol.asyncIterator] &lt;span class="o"&gt;(&lt;/span&gt;deno:runtime/js/30_fs.js:125:16&lt;span class="o"&gt;)&lt;/span&gt;
    at async readFolder &lt;span class="o"&gt;(&lt;/span&gt;https://deno.land/x/destjs@v0.2.0/bootstrap/middlewares.ts:8:20&lt;span class="o"&gt;)&lt;/span&gt;
    at async initializeMiddlewares &lt;span class="o"&gt;(&lt;/span&gt;https://deno.land/x/destjs@v0.2.0/bootstrap/middlewares.ts:27:3&lt;span class="o"&gt;)&lt;/span&gt;
    at async createApp &lt;span class="o"&gt;(&lt;/span&gt;https://deno.land/x/destjs@v0.2.0/mod.ts:19:3&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently &lt;code&gt;destjs&lt;/code&gt; will fail if it didn't find &lt;code&gt;middlewares&lt;/code&gt; directory under our project root directory. I'm not sure this behavior is by design or a bug - But for now we will create it even if we are not going to write any middlewares.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ tree &lt;span class="nt"&gt;-L&lt;/span&gt; 2
&lt;span class="nb"&gt;.&lt;/span&gt;
├── controllers
│   └── plants.controller.ts
├── main.ts
└── middlewares

2 directories, 2 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating this directory structure our command can execute succesfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-read&lt;/span&gt; ./main.ts
 Middlewares initialized! 0ms
Check file:///Users/shikloshi/projects/deno/hello-deno/controllers/plants.controller.ts
 Controllers initialized! 2106ms
 DestJS application ready at port 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test it using &lt;code&gt;curl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;curl&lt;/code&gt; http client we are able to submit an http request and verify that we are indeed getting the http response we are expecting to see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl localhost:8000/plants
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"plant"&lt;/span&gt;:&lt;span class="s2"&gt;"Monstera"&lt;/span&gt;,&lt;span class="s2"&gt;"beautiful"&lt;/span&gt;:true&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Permission flags
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Deno&lt;/code&gt;, unlike &lt;code&gt;Node.js&lt;/code&gt;, does not get allowed permissions by default to use host network and file system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;destjs&lt;/code&gt; is going to read from disk at build time so &lt;code&gt;deno&lt;/code&gt; will beed to get explicit permission to do so by adding &lt;code&gt;--allow-read&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;When running the server, it will have to use host network features and get explicit permissions using &lt;code&gt;--allow-net&lt;/code&gt;.
I encourage you to explore &lt;a href="https://deno.land/manual/getting_started/permissions"&gt;permission flags in depth&lt;/a&gt; when getting to know &lt;code&gt;Deno&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Whats next?
&lt;/h2&gt;

&lt;p&gt;In the next few chapter of this post We will try to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add persistence layer using &lt;code&gt;PostgreSQL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Authentication layer using &lt;code&gt;middlewares&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We will also explore &lt;code&gt;openAPI&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enhance our API to do some really interesting things, like saving plants in DB and checking when it was last watered.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Further reading
&lt;/h3&gt;

&lt;p&gt;If you liked this piece and want to deepen your understanding of some of the underlying concepts. Here are some links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://oakserver.github.io/oak/"&gt;Oak server&lt;/a&gt; -  middleware framework for Deno's native HTTP server. 'destjs' use it under the hood.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.nestjs.com/"&gt;NestJS&lt;/a&gt; - amazing framework on top of &lt;code&gt;Express.js&lt;/code&gt; that is being "ported", so to speak, into &lt;code&gt;Deno&lt;/code&gt;. It has great concepts and helps us write business logic on top of well designed construct. &lt;/li&gt;
&lt;li&gt;Ryan Dahl &lt;a href="https://www.youtube.com/watch?v=M3BM9TB-8yA&amp;amp;t=1s"&gt;first introducing&lt;/a&gt; &lt;code&gt;Deno&lt;/code&gt; - Recommended!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned. &lt;/p&gt;

</description>
      <category>deno</category>
      <category>typescript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
