<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Marc Pàmpols</title>
	<atom:link href="https://www.marcpampols.net/en/feed/?simply_static_page=9642" rel="self" type="application/rss+xml" />
	<link>https://www.marcpampols.net/</link>
	<description>Head of Digital / CTO at Rodi Motor Services &#38; REDD Parts · Building UptimeHouse.com</description>
	<lastBuildDate>Sun, 24 May 2020 13:16:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.5</generator>

<image>
	<url>https://www.marcpampols.net/wp-content/uploads/2024/12/cropped-image-32x32.jpg</url>
	<title>Marc Pàmpols</title>
	<link>https://www.marcpampols.net/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">176384913</site>	<item>
		<title>How to create your first REST API with Deno</title>
		<link>https://www.marcpampols.net/en/how-to-create-your-first-rest-api-with-deno/</link>
		
		<dc:creator><![CDATA[mpampols]]></dc:creator>
		<pubDate>Sun, 24 May 2020 13:12:08 +0000</pubDate>
				<category><![CDATA[Sin categoría]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Deno]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://www.marcpampols.net/?p=425</guid>

					<description><![CDATA[In this post I will explain step by step how to create a REST API with Deno. There is no need to explain the steps to install Deno. They are very well described on the official website. For this example I have used VS Code, for which this official plugin exists. What is Deno? Deno &#8230; <a href="https://www.marcpampols.net/en/how-to-create-your-first-rest-api-with-deno/" class="more-link">Continue reading <span class="screen-reader-text">How to create your first REST API with Deno</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>In this post I will explain step by step how to create a REST API with Deno.</p>



<p>There is no need to explain the <a href="https://deno.land/#installation" target="_blank" aria-label="steps to install Deno (opens in a new tab)" rel="noreferrer noopener nofollow" class="rank-math-link">steps to install Deno</a>. They are very well described on the official website. For this example I have used VS Code, for which this<a href="https://marketplace.visualstudio.com/items?itemName=justjavac.vscode-deno" target="_blank" aria-label=" (opens in a new tab)" rel="noreferrer noopener nofollow" class="rank-math-link"> official plugin</a> exists.</p>



<h2 class="wp-block-heading">What is Deno?</h2>



<p>Deno is very similar to Node, but what Deno is trying to do is to have a safer runtime and correcting the base errors that Node had. <strong>Deno is safe by default</strong>. This means that it does not have access to your hard drive, nor to your network. <strong>He will have it only if you give it to him.</strong> Node, on the other hand, has access to practically everything as soon as it is installed.</p>



<p>For example, if we follow the official guide and execute the first command, we will see that it works without issues.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">deno run https://deno.land/std/examples/welcome.ts</code></pre>



<p>But if we do it with the example that follows:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">import { serve } from "https://deno.land/std@0.52.0/http/server.ts";
const s = serve({ port: 8000 });

console.log("http://localhost:8000/");
for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}</code></pre>



<p>We will encounter a network access permission error:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">Compile file://welcome.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at listen ($deno$/net.ts:152:22)
    at serve (https://deno.land/std@0.52.0/http/server.ts:261:20)
    at file://welcome.ts:2:11</code></pre>



<p>This happens because the first example does not need any additional access to work, but the second needs access to our network. Deno, having security by default, does not allow us to do it unless we grant extra permission to do so.</p>



<p>In this example, you can run it with the &#8211;allow-net parameter, and it will work.</p>



<p>The same goes for files, in this case we need &#8211;allow-read</p>



<h2 class="wp-block-heading">Create an API with Deno</h2>



<p>What a better way to start playing with Deno than by <strong>creating our first REST API.</strong> <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>With this little tutorial I am going to create a very simple array of movies and the 5 methods to list, search, create, update, and delete elements.</p>



<p>The first step is to create an index file. In this case <strong>app.ts</strong>. The first thing will be to load <a href="https://oakserver.github.io/oak/" target="_blank" aria-label="Oak (opens in a new tab)" rel="noreferrer noopener nofollow" class="rank-math-link">Oak</a>, a middleware framework for Deno&#8217;s HTTP server. <strong>Oak </strong>is inspired by <strong>Koa</strong>, a middleware for<strong> Node.js</strong>. It seems that they continue with the pun. In the end, it helps us make writing APIs easier.</p>



<p>It is a fairly simple example that is practically self-explanatory. The server will listen on port 4000 and load the routes defined in the <strong>router.ts </strong>file that we will see right after. In the file <strong>./api/controller.ts</strong> I will put the definition of the functions for the different endpoints.</p>



<pre title="./app.js" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">import { Application } from "https://deno.land/x/oak/mod.ts";
import router from "./router.ts";
import {
  getMovies,
  getMovie,
  createMovie,
  updateMovie,
  deleteMovie,
} from "./api/controller.ts";

const env = Deno.env.toObject();
const HOST = env.HOST || "127.0.0.1";
const PORT = env.PORT || 4000;

const app = new Application();

app.use(router.routes());
app.use(router.allowedMethods());

console.log(`API is listening on ${HOST}:${PORT}...`);
await app.listen(`${HOST}:${PORT}`);</code></pre>



<p>It&#8217;s time to define the routes in the <strong>router.ts</strong> file. Here we will also import the Oak Router and the definitions that we will create in the <strong>controller.ts</strong></p>



<p>We instantiate a Router and define the 5 commented routes.</p>



<figure class="wp-block-table"><table><tbody><tr><td><strong>Method</strong></td><td><strong>Function</strong></td></tr><tr><td>getMovies</td><td>Returns all the movies</td></tr><tr><td>getMovie</td><td>Returns a movie given it&#8217;s ID</td></tr><tr><td>createMovie</td><td>Creates a new movie</td></tr><tr><td>updateMovie</td><td>Updates an existing movie</td></tr><tr><td>deleteMovie</td><td>Deletes a movie</td></tr></tbody></table></figure>



<pre title="./router.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">import { Router } from "https://deno.land/x/oak/mod.ts";
import {
  getMovies,
  getMovie,
  createMovie,
  updateMovie,
  deleteMovie,
} from "./api/controller.ts";

const router = new Router();

router
  .get("/movies", getMovies)
  .get("/movie/:id", getMovie)
  .post("/movies", createMovie)
  .put("/movies/:id", updateMovie)
  .delete("/movies/:id", deleteMovie);

export default router;
</code></pre>



<p>Now it&#8217;s time to create the <strong>controller.ts </strong>file to define the API methods and the with the test database.</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">interface Movie {
  id: string;
  title: string;
  rating: number;
}</code></pre>



<p>Then, the movies array.</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">/**
 * Sample array with movies
 */
let movies: Array&lt;Movie> = [
  {
    id: "1",
    title: "TENET",
    rating: 10,
  },
  {
    id: "2",
    title: "No Time to Die",
    rating: 8,
  },
  {
    id: "3",
    title: "The Way Back",
    rating: 7,
  },
  {
    id: "4",
    title: "The Invisible Man",
    rating: 9,
  },
  {
    id: "5",
    title: "Onward",
    rating: 8,
  },
];</code></pre>



<p>And now, the different methods starting with the one that <strong>lists all the movies</strong>. It is really that simple:</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">/**
 * Returns all the movies in database
 */
const getMovies = ({ response }: { response: any }) => {
  response.body = movies;
};</code></pre>



<p>Let&#8217;s go to the next one, the one in charge of <strong>returning a movie from an ID</strong> that we can pass as a parameter.</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">/**
 * Returns a movie by id
 */
const getMovie = ({
  params,
  response,
}: {
  params: { id: string };
  response: any;
}) => {
  const movie = movies.filter((movie) => movie.id == params.id)[0];
  if (movie) {
    response.status = 200;
    response.body = movie;
  } else {
    response.status = 404;
    response.body = { message: "404 Not found" };
  }
};</code></pre>



<p>If we try to launch the request with <strong>Postman</strong>, we will see that it works.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="1019" height="374" src="https://www.marcpampols.net/wp-content/uploads/2020/05/image-12.png" alt="image 12" class="wp-image-412" title="How to create your first REST API with Deno 1" srcset="https://www.marcpampols.net/wp-content/uploads/2020/05/image-12.png 1019w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-12-300x110.png 300w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-12-768x282.png 768w" sizes="(max-width: 1019px) 100vw, 1019px" /><figcaption>Lanzamos la petición para un ID en concreto.</figcaption></figure></div>



<p>It is the turn of the <strong>createMovie </strong>method to create a movie. The code is the following:</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">/**
 * Creates a new movie
 */
const createMovie = async ({
  request,
  response,
}: {
  request: any;
  response: any;
}) => {
  const body = await request.body();
  const movie: Movie = body.value;
  movies.push(movie);
  response.body = { success: true, data: movie };
  response.status = 201;
};</code></pre>



<p>If we launch the test request, the server will reply with a message containing the recently created movie data.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img decoding="async" width="754" height="528" src="https://www.marcpampols.net/wp-content/uploads/2020/05/image-14.png" alt="image 14" class="wp-image-414" title="How to create your first REST API with Deno 2" srcset="https://www.marcpampols.net/wp-content/uploads/2020/05/image-14.png 754w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-14-300x210.png 300w" sizes="(max-width: 754px) 100vw, 754px" /></figure></div>



<p>If we then launch the request to return all the movies, we will see how the new one appears correctly.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img decoding="async" width="697" height="809" src="https://www.marcpampols.net/wp-content/uploads/2020/05/image-15.png" alt="image 15" class="wp-image-415" title="How to create your first REST API with Deno 3" srcset="https://www.marcpampols.net/wp-content/uploads/2020/05/image-15.png 697w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-15-258x300.png 258w" sizes="(max-width: 697px) 100vw, 697px" /></figure></div>



<p>It is the turn of the <strong>updateMovie </strong>method to <strong>update a movie</strong>. The code is:</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">/**
 * Updates an existing movie
 */
const updateMovie = async ({
  params,
  request,
  response,
}: {
  params: { id: string };
  request: any;
  response: any;
}) => {
  const movie = movies.filter((movie) => movie.id == params.id)[0];
  if (movie) {
    const body = await request.body();
    movie.title = body.value.title;
    movie.rating = body.value.rating;
    response.status = 200;
    response.body = {
      success: true,
      data: movies,
    };
  } else {
    response.status = 404;
    response.body = {
      success: false,
      message: "Movie not found",
    };
  }
};</code></pre>



<p>We launch the corresponding <strong>PUT </strong>request with <strong>Postman</strong>, and we will get the correct response.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="956" height="580" src="https://www.marcpampols.net/wp-content/uploads/2020/05/image-17.png" alt="image 17" class="wp-image-417" title="How to create your first REST API with Deno 4" srcset="https://www.marcpampols.net/wp-content/uploads/2020/05/image-17.png 956w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-17-300x182.png 300w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-17-768x466.png 768w" sizes="(max-width: 956px) 100vw, 956px" /></figure></div>



<p>And finally, we only have the <strong>deleteMovie method</strong> that, in this case, deletes a movie from a given id. What I do is use the filter () to update the array keeping all the movies with a different id than the one sent.</p>



<pre title="./api/controller.ts" class="wp-block-code"><code lang="typescript" class="language-typescript line-numbers">/**
 * Deletes a movie by a given id
 */
const deleteMovie = ({
  params,
  response,
}: {
  params: { id: string };
  response: any;
}) => {
  movies = movies.filter((movie) => movie.id !== params.id);
  response.status = 200;
  response.body = { success: true, message: "Movie removed" };
};</code></pre>



<p>We try with Postman …</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="932" height="464" src="https://www.marcpampols.net/wp-content/uploads/2020/05/image-19.png" alt="image 19" class="wp-image-419" title="How to create your first REST API with Deno 5" srcset="https://www.marcpampols.net/wp-content/uploads/2020/05/image-19.png 932w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-19-300x149.png 300w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-19-768x382.png 768w" sizes="(max-width: 932px) 100vw, 932px" /></figure></div>



<p>And effectively the movie with id = 1 just disappeared <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="633" src="https://www.marcpampols.net/wp-content/uploads/2020/05/image-21-1024x633.png" alt="image 21" class="wp-image-421" title="How to create your first REST API with Deno 6" srcset="https://www.marcpampols.net/wp-content/uploads/2020/05/image-21-1024x633.png 1024w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-21-300x186.png 300w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-21-768x475.png 768w, https://www.marcpampols.net/wp-content/uploads/2020/05/image-21.png 1043w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>You can download all the source code for this example in <a aria-label="this repository  (opens in a new tab)" href="https://github.com/mpampols/deno.restapi" target="_blank" rel="noreferrer noopener nofollow" class="rank-math-link">this repository </a>from my GitHub.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">425</post-id>	</item>
	</channel>
</rss>
