{"id":298489,"date":"2020-02-10T21:00:20","date_gmt":"2020-02-10T21:00:20","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=298489"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=298489","title":{"rendered":"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e API \u043d\u0430 Deno"},"content":{"rendered":"\n<div class=\"post__text post__text-html\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/487806\/\">\u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e API \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Deno. Deno \u2014 \u043d\u043e\u0432\u0435\u0439\u0448\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Javascript \u0438 Typescript, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u043c Node.js \u2014 \u0420\u0430\u0439\u0430\u043d\u043e\u043c \u0414\u0430\u043b\u0435\u043c.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xm\/88\/u1\/xm88u1dikmhqu-fsollr1wdxy-q.jpeg\"><br \/>  <a name=\"habracut\"><\/a><br \/>  <b>\u041d\u0430\u0448\u0438 \u0446\u0435\u043b\u0438<\/b>:<\/p>\n<ul>\n<li>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c API, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/li>\n<li>\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b GET, POST, PUT \u0438 DELETE<\/li>\n<li>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 JSON \u0444\u0430\u0439\u043b<\/li>\n<li>\u0412\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/li>\n<\/ul>\n<p>   \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u2014 Deno. Deno \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 Typescript \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Deno \u0432\u0435\u0440\u0441\u0438\u0438 0.22 \u0438 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445.<br \/>  \u0412\u0435\u0440\u0441\u0438\u044e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e Deno \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <i>deno version<\/i> \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435.<\/p>\n<h3>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">handlers middlewares models services config.ts index.ts routing.ts<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u043a\u0430\u043a \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Node.js.<\/p>\n<ul>\n<li><i>handlers<\/i> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432<\/li>\n<li><i>middlewares<\/i> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u044b \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435<\/li>\n<li><i>models<\/i> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/li>\n<li><i>services<\/i> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u2026 \u0441\u0435\u0440\u0432\u0438\u0441\u044b!<\/li>\n<li><i>config.ts<\/i> \u2014 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/li>\n<li><i>index.ts<\/i> \u2014 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/li>\n<li><i>routing.ts<\/i> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b API<\/li>\n<\/ul>\n<p>  <\/p>\n<h3>\u0412\u044b\u0431\u043e\u0440 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430<\/h3>\n<p>  \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0434\u043b\u044f Node.js. \u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u2014 <b>Express<\/b>. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f Express\u2019a \u2014 <b>Koa<\/b>. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, Deno \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Node.js \u0438 \u0432\u044b\u0431\u043e\u0440 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f Deno, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u043d \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 Koa \u2014 <b>Oak<\/b>. \u041c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0438\u043c \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 Koa, \u043d\u0435 \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0439\u0442\u0435, \u043e\u043d \u043c\u043d\u043e\u0433\u0438\u043c \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 Express.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>  <i>index.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { Application } from &quot;https:\/\/deno.land\/x\/oak\/mod.ts&quot;; import { APP_HOST, APP_PORT } from &quot;.\/config.ts&quot;; import router from &quot;.\/routing.ts&quot;; import notFound from &quot;.\/handlers\/notFound.ts&quot;; import errorMiddleware from &quot;.\/middlewares\/error.ts&quot;;  const app = new Application();  app.use(errorMiddleware); app.use(router.routes()); app.use(router.allowedMethods()); app.use(notFound);  console.log(`Listening on ${APP_PORT}...`);  await app.listen(`${APP_HOST}:${APP_PORT}`); <\/code><\/pre>\n<p>  \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0434\u043d\u0443 \u0438\u0437 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0444\u0438\u0448\u0435\u043a Deno \u2014 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e: \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c middleware, \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0438, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440. \u0412\u0441\u0435 \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Express \u0438\u043b\u0438 Koa.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/h3>\n<p>  <i>config.ts<\/i>  <\/p>\n<pre><code class=\"javascript\">const env = Deno.env(); export const APP_HOST = env.APP_HOST || &quot;127.0.0.1&quot;; export const APP_PORT = env.APP_PORT || 4000; export const DB_PATH = env.DB_PATH || &quot;.\/db\/users.json&quot;; <\/code><\/pre>\n<p>  \u041d\u0430\u0448 \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0438\u0437 \u0441\u0440\u0435\u0434\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u043d\u043e \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <i>Deno.env()<\/i> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c <i>process.env<\/i> \u0432 Node.js.<\/p>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/h3>\n<p>  <i>models\/user.ts<\/i><\/p>\n<pre><code class=\"javascript\">export interface User {   id: string;   name: string;   role: string;   jiraAdmin: boolean;   added: Date; } <\/code><\/pre>\n<p>  <\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u043c\u0438<\/h3>\n<p>  <i>routing.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { Router } from &quot;https:\/\/deno.land\/x\/oak\/mod.ts&quot;;  import getUsers from &quot;.\/handlers\/getUsers.ts&quot;; import getUserDetails from &quot;.\/handlers\/getUserDetails.ts&quot;; import createUser from &quot;.\/handlers\/createUser.ts&quot;; import updateUser from &quot;.\/handlers\/updateUser.ts&quot;; import deleteUser from &quot;.\/handlers\/deleteUser.ts&quot;;  const router = new Router();  router   .get(&quot;\/users&quot;, getUsers)   .get(&quot;\/users\/:id&quot;, getUserDetails)   .post(&quot;\/users&quot;, createUser)   .put(&quot;\/users\/:id&quot;, updateUser)   .delete(&quot;\/users\/:id&quot;, deleteUser);  export default router; <\/code><\/pre>\n<p>  \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432 \u043d\u0435\u0433\u043e. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0432\u044b \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043a\u043e\u0434 \u0438\u0437 Express \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0435 \u0442\u0430\u043a \u043b\u0438?<\/p>\n<h3>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432<\/h3>\n<p>  <i>handlers\/getUsers.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { getUsers } from &quot;..\/services\/users.ts&quot;;  export default async ({ response }) =&gt; {   response.body = await getUsers(); }; <\/code><\/pre>\n<p>  \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 Koa, \u0442\u043e \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u044e. \u041e\u0431\u044a\u0435\u043a\u0442 <i>response<\/i> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c <i>res<\/i> \u0432 Express. \u041e\u0431\u044a\u0435\u043a\u0442 <i>res<\/i> \u0432 Express \u0438\u043c\u0435\u0435\u0442 \u043f\u0430\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 <i>json<\/i> \u0438\u043b\u0438 <i>send<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043b\u0443\u0436\u0430\u0442 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430. \u0412 Oak \u0438 Koa \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <i>response.body<\/i>.<\/p>\n<p>  <i>handlers\/getUserDetails.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { getUser } from &quot;..\/services\/users.ts&quot;;  export default async ({ params, response }) =&gt; {   const userId = params.id;    if (!userId) {     response.status = 400;     response.body = { msg: &quot;Invalid user id&quot; };     return;   }    const foundUser = await getUser(userId);   if (!foundUser) {     response.status = 404;     response.body = { msg: `User with ID ${userId} not found` };     return;   }    response.body = foundUser; }; <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0442\u043e\u0436\u0435 \u0432\u0441\u0435 \u043b\u0435\u0433\u043a\u043e. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043d\u0443\u0436\u043d\u044b\u043c Id.<\/p>\n<p>  <i>handlers\/createUser.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { createUser } from &quot;..\/services\/users.ts&quot;;  export default async ({ request, response }) =&gt; {   if (!request.hasBody) {     response.status = 400;     response.body = { msg: &quot;Invalid user data&quot; };     return;   }    const {     value: { name, role, jiraAdmin }   } = await request.body();    if (!name || !role) {     response.status = 422;     response.body = { msg: &quot;Incorrect user data. Name and role are required&quot; };     return;   }    const userId = await createUser({ name, role, jiraAdmin });    response.body = { msg: &quot;User created&quot;, userId }; }; <\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>  <i>handlers\/updateUser.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { updateUser } from &quot;..\/services\/users.ts&quot;;  export default async ({ params, request, response }) =&gt; {   const userId = params.id;    if (!userId) {     response.status = 400;     response.body = { msg: &quot;Invalid user id&quot; };     return;   }    if (!request.hasBody) {     response.status = 400;     response.body = { msg: &quot;Invalid user data&quot; };     return;   }    const {     value: { name, role, jiraAdmin }   } = await request.body();    await updateUser(userId, { name, role, jiraAdmin });    response.body = { msg: &quot;User updated&quot; }; }; <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c ID \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>  <i>handlers\/deleteUser.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { deleteUser, getUser } from &quot;..\/services\/users.ts&quot;;  export default async ({ params, response }) =&gt; {   const userId = params.id;    if (!userId) {     response.status = 400;     response.body = { msg: &quot;Invalid user id&quot; };     return;   }    const foundUser = await getUser(userId);   if (!foundUser) {     response.status = 404;     response.body = { msg: `User with ID ${userId} not found` };     return;   }    await deleteUser(userId);   response.body = { msg: &quot;User deleted&quot; }; }; <\/code><\/pre>\n<p>  \u041e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439.<\/p>\n<p>  <i>handlers\/notFound.ts<\/i><\/p>\n<pre><code class=\"javascript\">export default ({ response }) =&gt; {   response.status = 404;   response.body = { msg: &quot;Not Found&quot; }; }; <\/code><\/pre>\n<p>  <\/p>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/h3>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430.<\/p>\n<p>  <i>services\/createId.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { v4 as uuid } from &quot;https:\/\/deno.land\/std\/uuid\/mod.ts&quot;;  export default () =&gt; uuid.generate(); <\/code><\/pre>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 id. \u0412\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c uuid \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Deno \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430.<\/p>\n<p>  <i>services\/db.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { DB_PATH } from &quot;..\/config.ts&quot;; import { User } from &quot;..\/models\/user.ts&quot;;  export const fetchData = async (): Promise&lt;User[]&gt; =&gt; {   const data = await Deno.readFile(DB_PATH);    const decoder = new TextDecoder();   const decodedData = decoder.decode(data);    return JSON.parse(decodedData); };  export const persistData = async (data): Promise&lt;void&gt; =&gt; {   const encoder = new TextEncoder();   await Deno.writeFile(DB_PATH, encoder.encode(JSON.stringify(data))); }; <\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u043e\u0433\u0430\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 JSON \u0444\u0430\u0439\u043b\u043e\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<br \/>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430. \u0424\u0443\u043d\u043a\u0446\u0438\u044f readFile \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <i>Uint8Array<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u0437\u0430\u043d\u0435\u0441\u0442\u0438 \u0432 JSON \u0444\u0430\u0439\u043b, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0442\u0438\u043f <i>String<\/i>. <\/p>\n<p>  \u041d\u0430 \u0438 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>  <i>services\/users.ts<\/i><\/p>\n<pre><code class=\"javascript\">import { fetchData, persistData } from &quot;.\/db.ts&quot;; import { User } from &quot;..\/models\/user.ts&quot;; import createId from &quot;..\/services\/createId.ts&quot;;  type UserData = Pick&lt;User, &quot;name&quot; | &quot;role&quot; | &quot;jiraAdmin&quot;&gt;;  export const getUsers = async (): Promise&lt;User[]&gt; =&gt; {   const users = await fetchData();    \/\/ sort by name   return users.sort((a, b) =&gt; a.name.localeCompare(b.name)); };  export const getUser = async (userId: string): Promise&lt;User | undefined&gt; =&gt; {   const users = await fetchData();    return users.find(({ id }) =&gt; id === userId); };  export const createUser = async (userData: UserData): Promise&lt;string&gt; =&gt; {   const users = await fetchData();    const newUser: User = {     id: createId(),     name: String(userData.name),     role: String(userData.role),     jiraAdmin: &quot;jiraAdmin&quot; in userData ? Boolean(userData.jiraAdmin) : false,     added: new Date()   };    await persistData([...users, newUser]);    return newUser.id; };  export const updateUser = async (   userId: string,   userData: UserData ): Promise&lt;void&gt; =&gt; {   const user = await getUser(userId);    if (!user) {     throw new Error(&quot;User not found&quot;);   }    const updatedUser = {     ...user,     name: userData.name !== undefined ? String(userData.name) : user.name,     role: userData.role !== undefined ? String(userData.role) : user.role,     jiraAdmin:       userData.jiraAdmin !== undefined         ? Boolean(userData.jiraAdmin)         : user.jiraAdmin   };    const users = await fetchData();   const filteredUsers = users.filter(user =&gt; user.id !== userId);    persistData([...filteredUsers, updatedUser]); };  export const deleteUser = async (userId: string): Promise&lt;void&gt; =&gt; {   const users = await getUsers();   const filteredUsers = users.filter(user =&gt; user.id !== userId);    persistData(filteredUsers); }; <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043d\u043e \u044d\u0442\u043e \u0447\u0438\u0441\u0442\u044b\u0439 Typescript.<\/p>\n<h3>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h3>\n<p>  \u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0445\u0443\u0436\u0435, \u0447\u0435\u043c \u0442\u043e, \u0447\u0442\u043e \u0441\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439? \u0412\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u043a\u0440\u0430\u0448\u043d\u0443\u0442\u044c\u0441\u044f. \u0414\u043b\u044f \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 try\/catch \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435. \u041d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0438\u0437\u044f\u0449\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u0434\u043e\u0431\u0430\u0432\u0438\u043c middleware \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c \u0438 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c.<\/p>\n<p>  <i>middlewares\/error.ts<\/i><\/p>\n<pre><code class=\"javascript\">export default async ({ response }, next) =&gt; {   try {     await next();   } catch (err) {     response.status = 500;     response.body = { msg: err.message };   } }; <\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0430\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430. <\/p>\n<p>  <i>db\/users.json<\/i><\/p>\n<pre><code class=\"json\">[   {     &quot;id&quot;: &quot;1&quot;,     &quot;name&quot;: &quot;Daniel&quot;,     &quot;role&quot;: &quot;Software Architect&quot;,     &quot;jiraAdmin&quot;: true,     &quot;added&quot;: &quot;2017-10-15&quot;   },   {     &quot;id&quot;: &quot;2&quot;,     &quot;name&quot;: &quot;Markus&quot;,     &quot;role&quot;: &quot;Frontend Engineer&quot;,     &quot;jiraAdmin&quot;: false,     &quot;added&quot;: &quot;2018-09-01&quot;   } ] <\/code><\/pre>\n<p>  \u0412\u043e\u0442 \u0438 \u0432\u0441\u0435! \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <code>deno -A index.ts<\/code><\/p>\n<p>  \u0424\u043b\u0430\u0433 \u201c\u0410\u201d \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435.<\/p>\n<p>  \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 (Download) \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 (Compile). \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0437\u0430\u0432\u0435\u0442\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430:<\/p>\n<p>  <code>Listening on 4000<\/code><\/p>\n<h3>\u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u0438\u0442\u043e\u0433\u0438<\/h3>\n<p>  <b>\u041a\u0430\u043a\u0438\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c?<\/b><\/p>\n<ol>\n<li>\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <b>Deno<\/b> \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f\/\u0437\u0430\u043f\u0438\u0441\u0438 \u0444\u0430\u0439\u043b\u043e\u0432<\/li>\n<li><b>uuid<\/b> \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Deno \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e id<\/li>\n<li><b>oak<\/b> \u2014 third-party \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Koa \u0434\u043b\u044f Node.js<\/li>\n<li>\u0427\u0438\u0441\u0442\u044b\u0439 Typescript, \u043e\u0431\u044a\u0435\u043a\u0442\u044b TextEncode \u0438\u043b\u0438 JSON, \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0432 Javascript<\/li>\n<\/ol>\n<p>  <\/p>\n<h3>\u0412 \u0447\u0435\u043c \u0436\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 Node.js?<\/h3>\n<p>  <\/p>\n<ul>\n<li>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0434\u043b\u044f Typescript \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 ts-node. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <i>deno index.ts<\/i><\/li>\n<li>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434 \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438<\/li>\n<li>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 package.json \u0438 package-lock.json<\/li>\n<li>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 node_modules \u0432 \u043a\u043e\u0440\u0435\u043d\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0412\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u044d\u0448\u0435<\/li>\n<\/ul>\n<p>  \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u043f\u043e <a href=\"https:\/\/github.com\/kryz81\/deno-api-example\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a>.<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/487806\/\"> https:\/\/habr.com\/ru\/post\/487806\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/487806\/\">\u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e API \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Deno. Deno \u2014 \u043d\u043e\u0432\u0435\u0439\u0448\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Javascript \u0438 Typescript, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u043c Node.js \u2014 \u0420\u0430\u0439\u0430\u043d\u043e\u043c \u0414\u0430\u043b\u0435\u043c.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xm\/88\/u1\/xm88u1dikmhqu-fsollr1wdxy-q.jpeg\">  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-298489","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/298489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=298489"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/298489\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=298489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=298489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=298489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}