<!DOCTYPE html>
    <html lang="vi" xmlns="http://www.w3.org/1999/xhtml" prefix="og: http://ogp.me/ns#">
    <head>
<title>Cách xây dựng API đơn giản bằng Deno</title>
<meta name="description" content="Cách xây dựng API đơn giản bằng Deno - Savefile - Tin Tức -...">
<meta name="author" content=".: Nguoicodonvn2008.info - Cõi lòng người cô đơn :.">
<meta name="copyright" content=".: Nguoicodonvn2008.info - Cõi lòng người cô đơn :. [admin@nguoicodonvn2008.info]">
<meta name="robots" content="index, archive, follow, noodp">
<meta name="googlebot" content="index,archive,follow,noodp">
<meta name="msnbot" content="all,index,follow">
<meta name="generator" content="NukeViet v4.5">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta property="og:title" content="Cách xây dựng API đơn giản bằng Deno">
<meta property="og:type" content="website">
<meta property="og:description" content="Savefile - Tin Tức - https&#x3A;&#x002F;&#x002F;www.nguoicodonvn2008.info&#x002F;vi&#x002F;news&#x002F;savefile&#x002F;kien-thuc-may-tinh&#x002F;cach-xay-dung-api-don-gian-bang-deno-7477.html">
<meta property="og:site_name" content=".&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;.">
<meta property="og:url" content="https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/cach-xay-dung-api-don-gian-bang-deno-7477.html">
<link rel="shortcut icon" href="https://www.nguoicodonvn2008.info/favicon.ico">
<link rel="canonical" href="https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/cach-xay-dung-api-don-gian-bang-deno-7477.html">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/" title="Tin Tức" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/karaoke-dual/" title="Tin Tức - Karaoke Dual" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/nhac-tre/" title="Tin Tức - Nhạc trẻ" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tru-tinh/" title="Tin Tức - Trữ tình" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/nuoc-ngoai/" title="Tin Tức - Nước ngoài" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/remix/" title="Tin Tức - Remix" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tam-su-tinh-yeu/" title="Tin Tức - Tâm sự tình yêu" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tho-suu-tam/" title="Tin Tức - Thơ sưu tầm" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/cuoc-song/" title="Tin Tức - Cuộc sống" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/phan-mem/" title="Tin Tức - Phần mềm" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/kien-thuc-may-tinh/" title="Tin Tức - Kiến thức máy tính" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/hoc-tap/" title="Tin Tức - Học tập" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tai-lieu/" title="Tin Tức - Tài liệu" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/de-thi/" title="Tin Tức - Đề thi" type="application/rss+xml">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/assets/css/font-awesome.min.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/bootstrap.non-responsive.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/style.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/style.non-responsive.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/news.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/custom.css" type="text/css">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/jquery/jquery.min.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/language/vi.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/DOMPurify/purify3.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/global.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/site.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/news.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/main.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/custom.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/bootstrap.min.js" type="text/javascript">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/assets/css/font-awesome.min.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/bootstrap.non-responsive.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/style.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/style.non-responsive.css">
<link rel="StyleSheet" href="https://www.nguoicodonvn2008.info/themes/default/css/news.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/custom.css">
<style type="text/css">
	body{background: #fff;}
</style>
    </head>
    <body>
<div id="print">
	<div id="hd_print">
		<h2 class="pull-left">.&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;.</h2>
		<p class="pull-right"><a title=".&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;." href="https://www.nguoicodonvn2008.info/">https://www.nguoicodonvn2008.info</a></p>
	</div>
	<div class="clear"></div>
	<hr />
	<div id="content">
		<h1>Cách xây dựng API đơn giản bằng Deno</h1>
		<ul class="list-inline">
			<li>Thứ hai - 28/08/2023 10:04</li>
			<li class="hidden-print txtrequired"><em class="fa fa-print">&nbsp;</em><a title="In ra" href="javascript:;" onclick="window.print()">In ra</a></li>
			<li class="hidden-print txtrequired"><em class="fa fa-power-off">&nbsp;</em><a title="Đóng cửa sổ này" href="javascript:;" onclick="window.close()">Đóng cửa sổ này</a></li>
		</ul>
		<div class="clear"></div>
		<div id="hometext">
		</div>
				<div class="imghome">
			<img alt="Cách xây dựng API đơn giản bằng Deno" src="https://st.quantrimang.com/photos/image/2023/08/15/Deno-API-app-7.jpg" width="460" class="img-thumbnail" />
		</div>
		<div class="clear"></div>
		<div id="bodytext" class="clearfix">
			<p style="text-align: justify;"><strong>Deno</strong>&nbsp;là một runtime JavaScript được tích hợp trên V8, , cùng một công cụ JavaScript cung cấp năng lượng cho&nbsp;Google Chrome. Bạn có thể dùng Deno để xây dựng một API đơn giản.</p>

<p style="text-align: justify;"><img alt="Deno" data-i="0" data-src="https://st.quantrimang.com/photos/image/2023/08/15/Deno-API-app-7.jpg" data-was-processed="true" height="340" src="https://st.quantrimang.com/photos/image/2023/08/15/Deno-API-app-7.jpg" width="650" /></p>

<h2 style="text-align: justify;">Cài đặt Deno</h2>

<p style="text-align: justify;">Đầu tiên, bạn phải download và cài đặt nó. Bản cài của Deno thay đổi theo hệ điều hành.</p>

<p style="text-align: justify;">Trên macOS &amp; Linux, chạy lệnh cài:</p>

<pre id="pre0" style="text-align: justify;">
curl -fsSL https://deno.land/x/install/install.sh | sh</pre>

<p style="text-align: justify;">Trên Windows, bạn có thể cài Deno bằng Powershell:</p>

<pre id="pre1" style="text-align: justify;">
irm https://deno.land/install.ps1 | iex</pre>

<p style="text-align: justify;">Xác nhận cài đặt thành công bằng cách chạy lệnh sau:</p>

<pre id="pre2" style="text-align: justify;">
deno --version</pre>

<h2 style="text-align: justify;">Kết nối database</h2>

<p style="text-align: justify;">Ở hướng dẫn này, bạn sẽ dùng MongoDB làm database để duy trì dữ liệu từ API.</p>

<p style="text-align: justify;">Để kết nối app Deno với database MongoDB, tạo file db.js trong thư mục gốc của dự án và thêm khối code này bên dưới nó:</p>

<pre id="pre3" style="text-align: justify;">
// db.js
import { MongoClient } from &quot;https://deno.land/x/mongo@v0.30.1/mod.ts&quot;;
const client = new MongoClient();
try {
  await client.connect(&quot;mongodb://localhost:27017/todo&quot;);
  console.log(&quot;Connected to database&quot;);
} catch (err) {
  console.log(&quot;Error connecting to database&quot;, err);
}
const db = client.database(&quot;todo&quot;);
export default db;</pre>

<p style="text-align: justify;">Deno có một hệ thống quản lý package riêng cho việc nhập và quản lý trực tiếp các phần phụ thuộc từ URL.</p>

<p style="text-align: justify;">Ví dụ, khối code trên nhập MongoClient từ URL: https://deno.land/x/mongo@v0.30.1/mod.ts dẫn tới package này.</p>

<p style="text-align: justify;">Sau đó, dùng driver Deno MongoDB đã nhập (MongoClient), Deno thiết lập một kết nối giữa ứng dụng và database MongoDB cục bộ.</p>

<h2 style="text-align: justify;">Tạo mẫu database</h2>

<p style="text-align: justify;">Dù có thể tương tác với database MongoDB mà không cần tới mẫu database, làm việc này có thể dẫn tới code lộn xộn và ít có khả năng bảo trì.</p>

<p style="text-align: justify;">Để tránh điều đó, tạo file&nbsp;<strong>TodoModel.ts</strong>&nbsp;trong thư mục gốc của dự án và lên cấu trúc dữ liệu bằng cách thêm khối code bên dưới vào file:</p>

<pre id="pre4" style="text-align: justify;">
import db from &quot;./db.ts&quot;;
interface Todo {
  title: string;
  description: string;
  completed?: boolean;
}
const Todo = db.collection(&quot;todos&quot;);
export default Todo;</pre>

<p style="text-align: justify;">Khối code trên định nghĩa một interface Todo đại diện cho cấu trúc của một mục công việc đơn lẻ. Sau đó, sử dụng giao diện Todo, nó tạo một bộ sưu tập Todo bằng cách gọi phương thức bộ sưu tập được hiển thị bằng phiên bản MongoDB đã tạo trước đó của bạn.</p>

<h2 style="text-align: justify;">Tạo server với Oak</h2>

<p style="text-align: justify;">Oak là phần mềm trung gian cho máy chủ HTTP gốc của Deno. Nó được lấy cảm hứng từ Koa, một giải pháp thay thế cho Express.js.</p>

<p style="text-align: justify;">Để tạo một máy chủ với Oak, hãy tạo một tệp&nbsp;<strong>main.ts</strong>&nbsp;trong thư mục gốc của dự án và thêm khối mã bên dưới vào tệp của bạn.</p>

<pre id="pre5" style="text-align: justify;">
// main.ts
import { Application } from &quot;https://deno.land/x/oak/mod.ts&quot;;
import router from &quot;./router.ts&quot;;
const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());
await app.listen({ port: 8000 });
console.log(&quot;Server running on port 8000&quot;);</pre>

<p style="text-align: justify;">Khối code trên nhập<strong>&nbsp;Application</strong>&nbsp;từ URL Oak và tạo một phiên bản ứng dụng (app) lắng nghe lưu lượng truy cập đến trên cổng 8000.</p>

<p style="text-align: justify;">Dòng&nbsp;<strong>app.use(router.routes())&nbsp;</strong>đăng ký các tuyến của bộ định tuyến dưới dạng phần mềm trung gian trong ứng dụng Oak. Điều này có nghĩa là ứng dụng sẽ khớp các tuyến đã đăng ký với các yêu cầu đến và các trình xử lý tương ứng sẽ chạy nếu có kết quả trùng khớp.</p>

<p style="text-align: justify;">Dòng<strong>&nbsp;app.use(router.allowedMethods())</strong>&nbsp;xử lý các phương thức HTTP không được xác định rõ ràng trong bộ định tuyến. Ví dụ: nếu nó nhận được yêu cầu có phương thức không được hỗ trợ, chẳng hạn như yêu cầu PUT chưa đăng ký, middleware allowMethods() sẽ tự động gửi phản hồi thích hợp (ví dụ: 405 Method Not Allowed).</p>

<h2 style="text-align: justify;">Triển khai tính năng CRUD</h2>

<p style="text-align: justify;">Hướng dẫn này xe bao gồm một API todo đơn giản với tính năng CRUD.</p>

<p style="text-align: justify;">Tạo tệp router.ts trong thư mục gốc của dự án và thêm khối mã bên dưới vào tệp của bạn:</p>

<pre id="pre6" style="text-align: justify;">
import { Router } from &quot;https://deno.land/x/oak/mod.ts&quot;;
import Todo from &quot;./todoModel.ts&quot;;
import { ObjectId } from &quot;https://deno.land/x/mongo@v0.30.1/mod.ts&quot;;
const router = new Router(); // Create Router</pre>

<p style="text-align: justify;">Khối code trên nhập và tạo một phiên bản của bộ định tuyến Oak. Sử dụng ví dụ này, bạn có thể tạo các trình xử lý định tuyến cho các phương thức HTTP khác nhau bằng cách gọi các tên phương thức tương ứng (<strong>get</strong>,&nbsp;<strong>post</strong>,&nbsp;<strong>put</strong>,&nbsp;<strong>delete</strong>).</p>

<p style="text-align: justify;">Ví dụ: khối code bên dưới là một ví dụ về cách bạn có thể tạo trình xử lý tuyến đường GET trả về tất cả các tài liệu trong bộ sưu tập Todo của bạn.</p>

<pre id="pre7" style="text-align: justify;">
router
  .get(&quot;/api/todos&quot;, (ctx: RouterContext&lt;&quot;/api/todos&quot;&gt;) =&gt; {
    ctx.response.body = Todo.find();
  })</pre>

<p style="text-align: justify;">Để gửi một đối tượng phản hồi bằng Deno, bạn phải gán đối tượng response.body trên RouterContex cho đối tượng phản hồi. Điều tương tự cũng áp dụng cho code trạng thái.</p>

<p style="text-align: justify;">Để thêm trình xử lý lộ trình khác, bạn có thể xâu chuỗi chúng sang trình xử lý route trước đó.</p>

<p style="text-align: justify;">Ví dụ:</p>

<pre id="pre8" style="text-align: justify;">
.get(&quot;/api/todo/:id&quot;, async (ctx: RouterContext&lt;&quot;/api/todo/:id&quot;&gt;) =&gt; {
    try {
      const todo = await Todo.findOne({ _id: new ObjectId(ctx.params.id) });
      if (!todo) {
        ctx.response.status = 404;
        ctx.response.body = {
          msg: &quot;Todo not found&quot;,
        };
        return;
      }
      ctx.response.body = todo;
    } catch (error) {
      ctx.response.status = 500;
      ctx.response.body = {
        msg: &quot;Error getting todo&quot;,
        error,
      };
    }
  })</pre>

<p style="text-align: justify;">Khối code trên xác định trình xử lý route GET trả về một mục Todo duy nhất khớp với id trong thông số URL.</p>

<p style="text-align: justify;">Tiếp theo, xác định trình route CREATE để thêm tài liệu mới vào bộ sưu tập của bạn:</p>

<pre id="pre9" style="text-align: justify;">
.post(&quot;/api/todo/new&quot;, async (ctx: RouterContext&lt;&quot;/api/todo/new&quot;&gt;) =&gt; {
    const body = ctx.request.body();
    const todo = await body.value;
    if (!todo) {
      ctx.response.status = 400;
      ctx.response.body = { msg: &quot;Invalid data. Please provide a valid todo.&quot; };
      return;
    }
    const { title, description } = todo;
    if (!(title &amp;&amp; description)) {
      ctx.response.status = 400;
      ctx.response.body = {
        msg: &quot;Title or description missing. Please provide a valid todo.&quot;,
      };
      return;
    }
    try {
      await Todo.insertOne({
        title: todo.title,
        description: todo.description,
        completed: false,
      });
      ctx.response.status = 201;
      ctx.response.body = {
        msg: &quot;Todo added successfully&quot;,
      };
    } catch (error) {
      ctx.response.status = 500;
      ctx.response.body = {
        msg: &quot;Error adding todo&quot;,
        error,
      };
    }
  })</pre>

<p style="text-align: justify;">Tiếp theo, thêm trình xử lý route PUT cập nhật Todo dựa trên tham số id, với dữ liệu được gửi trong phần thân yêu cầu.</p>

<pre id="pre10" style="text-align: justify;">
.put(&quot;/api/todo/:id&quot;, async (ctx: RouterContext&lt;&quot;/api/todo/:id&quot;&gt;) =&gt; {
    try {
      const body = ctx.request.body();
      const todo = await body.value;
      await Todo.updateOne(
        { _id: new ObjectId(ctx.params.id) },
        { $set: { title: todo.title, description: todo.description } }
      );
      ctx.response.status = 200;
      ctx.response.body = {
        msg: &quot;Todo updated successfully&quot;,
      };
    } catch (error) {
      console.log(error);
      ctx.response.status = 500;
      ctx.response.body = {
        msg: &quot;Error updating todo&quot;,
        error: error.message,
      };
    }
  })</pre>

<p style="text-align: justify;">Cuối cùng, tạo trình xử lý route DELETE loại bỏ một Todo từ bộ sưu tập MongoDB:</p>

<pre id="pre11">
<code>.delete(&quot;/api/todo/:id&quot;, async (ctx: RouterContext&lt;&quot;/api/todo/:id&quot;&gt;) =&gt; {
    await Todo.deleteOne({ _id: new ObjectId(ctx.params.id) });

    ctx.response.status = 200;

    ctx.response.body = {
      msg: &quot;Todo deleted successfully&quot;,
    };
  });</code></pre>

<p style="text-align: justify;">Giờ khởi động app Deno bằng lệnh này:</p>

<pre id="pre12">
<code>deno run --allow-net --allow-read --allow-env --watch main.ts</code></pre>

<p style="text-align: justify;">Chúc các bạn thành công!</p>
		</div>
				<div id="author">
						<p>
				<strong>Nguồn tin:</strong>
				Quantrimang.com
			</p>
		</div>
	</div>
	<div id="footer" class="clearfix">
		<div id="url">
			<strong>URL của bản tin này: </strong><a href="https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/cach-xay-dung-api-don-gian-bang-deno-7477.html" title="Cách xây dựng API đơn giản bằng Deno">https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/cach-xay-dung-api-don-gian-bang-deno-7477.html</a>

		</div>
		<div class="clear"></div>
		<div class="copyright">
			&copy; .&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;.
		</div>
		<div id="contact">
			<a href="mailto:admin@nguoicodonvn2008.info">admin@nguoicodonvn2008.info</a>
		</div>
	</div>
</div>
        <div id="timeoutsess" class="chromeframe">
            Bạn đã không sử dụng Site, <a onclick="timeoutsesscancel();" href="https://www.nguoicodonvn2008.info/#">Bấm vào đây để duy trì trạng thái đăng nhập</a>. Thời gian chờ: <span id="secField"> 60 </span> giây
        </div>
        <div id="openidResult" class="nv-alert" style="display:none"></div>
        <div id="openidBt" data-result="" data-redirect=""></div>
		</script>
		<div class="car-top">
  <span><img src="https://www.nguoicodonvn2008.info/themes/default/images/car.png" alt=""></span>
</div>
<script src="https://www.nguoicodonvn2008.info/assets/js/jquery/jquery.min.js"></script>
<script>var nv_base_siteurl="/",nv_lang_data="vi",nv_lang_interface="vi",nv_name_variable="nv",nv_fc_variable="op",nv_lang_variable="language",nv_module_name="news",nv_func_name="savefile",nv_is_user=0, nv_my_ofs=-4,nv_my_abbr="EDT",nv_cookie_prefix="nv4c_e856T",nv_check_pass_mstime=1738000,nv_area_admin=0,nv_safemode=0,theme_responsive=0,nv_recaptcha_ver=2,nv_recaptcha_sitekey="",nv_recaptcha_type="image",XSSsanitize=1;</script>
<script src="https://www.nguoicodonvn2008.info/assets/js/language/vi.js"></script>
<script src="https://www.nguoicodonvn2008.info/assets/js/DOMPurify/purify3.js"></script>
<script src="https://www.nguoicodonvn2008.info/assets/js/global.js"></script>
<script src="https://www.nguoicodonvn2008.info/assets/js/site.js"></script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/news.js"></script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/main.js"></script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/custom.js"></script>
<script type="application/ld+json">
        {
            "@context": "https://schema.org",
            "@type": "Organization",
            "url": "https://www.nguoicodonvn2008.info",
            "logo": "https://www.nguoicodonvn2008.info/uploads/angel.gif"
        }
        </script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/bootstrap.min.js"></script>
<script type="text/javascript">
var $scrolltop = $('.car-top');
$scrolltop.on('click', function () {
    $('html,body').animate({
        scrollTop: 0
    }, 800);
    $(this).addClass("car-run");
    setTimeout(function(){ $scrolltop.removeClass('car-run');}, 1000);
    return false;
});
$(window).on('scroll', function ()
{ 
    if($(window).scrollTop() >= 200)
    {
        $scrolltop.addClass("show");
        $scrolltop.addClass("car-down");
    }
    else
    {
       $scrolltop.removeClass("show");
       setTimeout(function(){ $scrolltop.removeClass('car-down');}, 300);
    }
});
</script>
</body>
</html>