Я разработчик JavaScript/Node, который тайно любит (на самом деле любит и ободорожает) Deno. Я был огромным поклонником Deno с тех пор, как было объявлено, и я хотел играть с ним.
В этом руководстве ориентировано на создание набора API для отдыха для приложения TODO. Имейте в виду, что я не прикоснулся к базе данных здесь – я буду покрывать это в другой статье.
В любой момент, если вы чувствуете себя потерянным или хотите проверить ссылку, вот весь исходный код этого руководства: Глава 1: Дуб Отказ
Вещи, которые мы будем покрывать
- Создать базовый сервер
- Создать 5 API (маршруты/контроллер)
- Создайте промежуточное программное обеспечение для записи запросов API, так как они сделаны в консоли
- Создать не найден (404) промежуточное программное обеспечение Когда пользователь пытается получить доступ к неизвестному API
Что нам нужно
- Установленная версия DENO (не волнуйтесь, я пойду через это)
- Крошечный кусочек знаний о типографии
- Будет круто, если вы работали с узлом/Express до (не волнуйтесь, если у вас нет – это учебное пособие очень простое)
Давай начал
Первые вещи сначала давайте установим Deno. Я на компьютере Mac, поэтому я использую варево. Просто откройте свой терминал и введите:
$ brew install deno
Но если вы используете другую операционную систему, просто отправляйтесь на DENO.LAND Установка Отказ У них много способов легко установить его на вашу машину.
Как только у вас установлено, закройте терминал, откройте новый, и введите:
$ deno --version
Это должно выводить что-то вроде этого:
Потрясающие! С этим мы почти сделаем с 10% этого учебника.
Давайте перейдем вперед и создадим Backend API для нашего приложения Todo.
Настройка проекта
Прежде чем двигаться дальше, вот весь исходный код этого руководства: Глава 1: Дуб Отказ
Давайте начнем:
- Создайте новую папку и назовите ее Chapter_1: дуб (Но вы можете назвать это все, что вы хотите)
- Как только вы создаете папку просто
CDв ваш новый проект. Создайте файл под названием Server.ts и напишите следующий код в нем:
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const port: number = 8080;
console.log('running on port ', port);
await app.listen({ port });Давайте запустим этот файл. Откройте свой терминал и в своем типе корневой папки проекта:
$ deno run --allow-net server.ts
Я расскажу о том, что - Нота-сеть Флаг делает, но сейчас просто нести со мной?
Вы должны получить что-то подобное:
Что мы сделали до сих пор, создают сервер, который слушает порта 8080. Это не так много делает, помимо возможности работать по порту 8080.
Если вы использовали JavaScript раньше, одна вещь, которую вы могли бы заметить, мы импортируем пакеты по-другому. Мы должны сделать что-то вроде:
import { Application } from "https://deno.land/x/oak/mod.ts";
Когда вы запустите DENO RUN --- Разрешить-net В вашем терминале DENO будет смотреть на все ваши импорт и устанавливать их на месте на вашем компьютере, если они там нет.
Первый раз, когда вы запускаете это, он пойдет на этот URL https://deno.land/x/oak/mod.ts и установить дуб упаковка. Дуб в основном является каркасом DENO для написания API. Это поставит его где-то локально в вашем кэше.
В следующей строке мы делаем это:
const app = new Application();
Это создает новый экземпляр нашего приложения, и это будет основой всего, как вы прогрессируете дальше в этом руководстве. Вы можете добавить маршруты к экземпляру приложения, прикрепите промежуточное программное обеспечение, как журнал API, напишите 404 не найден и так далее.
Тогда мы пишем:
const port: number = 8080; // const port = 8080; // => can also be written like this
Оба одинаковы и делают то же самое. Единственная разница написана Порт-порт: Рассказывает Teamescript, что порт Переменная номера типа.
Если бы вы написали Порт-порт: Это будет бросить ошибку в вашем терминале, так как порт имеет тип Номер Отказ Но мы пытаемся назначить это Строка ценности “8080”.
Если вы хотите узнать больше о различных типах типов (каламбур), проверьте это очень простое и основное руководство по Основные типы по ThmyScript Отказ Просто дайте ему быстрый взгляд на 2-3 минуты и вернитесь сюда.
И в конце концов у нас есть:
console.log('running on port ', port);
await app.listen({ port });Мы просто удержим здесь номер порта и скажу Deno прослушать порт, который составляет 8080.
Это не так много. Давайте сделаем это что-то простое, как показать JSON Сообщение в вашем браузере при переходе на http: localhost: 8080 Отказ
Добавьте следующее в свой Server.ts файл:
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const port: number = 8080;
const router = new Router();
router.get("/", ({ response }: { response: any }) => {
response.body = {
message: "hello world",
};
});
app.use(router.routes());
app.use(router.allowedMethods());
console.log('running on port ', port);
await app.listen({ port });Новая вещь, добавленная вот то, что мы сейчас также импортируем Маршрутизатор вместе с Приложение от дуб в строке 1.
Далее, что мы делаем:
const router = new Router();
router.get("/", ({ response }: { response: any }) => {
response.body = {
message: "hello world",
};
});
app.use(router.routes());
app.use(router.allowedMethods());Мы создаем новый экземпляр маршрутизатора, делая Const Router () И тогда мы создаем новый маршрут под названием / который имеет тип Получить Отказ
Давайте сломаем это:
router.get("/", ({ response }: { response: any }) => {
response.body = {
message: "hello world",
};
});Router.get занимает 2 параметра. Первый – это маршрут, который мы установили на / И вторая функция. Сама функция принимает аргумент, который является объектом. Что я здесь делаю Разрушение Объект и получить только ответ Отказ
Далее я тип проверки ответ похоже на то, как я сделал Порт-порт:; Отказ Все, что я делаю, это {Ответ}: {Ответ: любой} который рассказывает Teamescript здесь, что ответ который у меня разрушился, может быть типа любой Отказ
любой Помогает вам избежать проверки типа в типографии. Вы можете прочитать больше об этом здесь Отказ
Тогда все, что я делаю, это берут это ответ Объект и настройка Ответ.body.message; Отказ
response.body = {
message: "hello world",
};Последнее, но не менее важное, мы просто добавляем эти две линии:
app.use(router.routes()); app.use(router.allowedMethods());
Это говорит Deno включать все маршруты на наш маршрутизатор (в настоящее время у нас есть только один), а следующая строка сообщает Deno, чтобы разрешить все методы для этого маршрута, как Получить, пост, поставить, удалить Отказ
И теперь мы сделаем. ✅ Давайте запустим это и посмотрим, что у нас есть:
$ deno run --allow-net server.ts
--- Разрешить-net Собственность сообщает Deno, что это приложение дает пользователю разрешение доступа к своему контенту через порт, открытый.
Теперь откройте свой любимый браузер и перейдите в http://localhost: 8080 . Вы увидите что-то вроде этого:
Честно говоря, самая сложная часть делается. Концептуально у нас там 60%.
Потрясающие.
Только одна последняя вещь, прежде чем мы начнем с нашего Todo API. Давайте заменим:
console.log('running on port ', port);
await app.listen({ port });с участием:
app.addEventListener("listen", ({ secure, hostname, port }) => {
const protocol = secure ? "https://" : "http://";
const url = `${protocol}${hostname ?? "localhost"}:${port}`;
console.log(`Listening on: ${port}`);
});
await app.listen({ port });Код, который у нас было раньше, было не очень точным, потому что мы были просто консольными входами в журнал сообщения, а затем ждем приложения для начала прослушивания в порту.
С более поздней версией мы ждем приложения, чтобы начать слушать порт И мы можем слушать, добавив слушатель события нашим приложение экземпляр со следующим: приложение .addeventListener. («Слушайте», ({безопасное, имя хоста, порт}) = > {} .
Первый параметр – это событие, которое мы хотим прослушать (что это Прослушать ?) а затем второй параметр – это объект, который мы разрушаем на {безопасное, имя хоста, порт} Отказ Безопасный это логическое значение, имя хоста – это строка, а порт является числом.
Теперь, когда мы запускаем наше приложение, он будет консидентом только после того, как приложение фактически запускает прослушивание порта.
Мы можем просто пойти на шаг вперед и сделать его более красочным. Давайте добавим новый модуль в верхнюю часть файла в Server.ts :
import { green, yellow } from "https://deno.land/std@0.53.0/fmt/colors.ts";
А затем внутри нашего метода слушателя событий мы можем заменить:
console.log(`Listening on: ${port}`);
с участием:
console.log(`${yellow("Listening on:")} ${green(url)}`);Теперь, когда мы делаем:
$ deno run --allow-net server.ts
Это покажет это в нашей консоли:
Если вы застряли где угодно, вы можете просто перейти к исходному коду этого учебника здесь .
Давайте создадим наши маршруты TODO API Далее.
- Создайте новую папку в вашей корневой папке под названием
маршрутыИ внутри этой папки создают файл под названиемTodo.ts. - В то же время в вашей корневой папке создайте новую папку под названием
контроллерыИ внутри этой папки создают файл под названиемTodo.ts.
Давайте сначала коснемся Контроллеры/TODO.TS файл:
export default {
getAllTodos: () => {},
createTodo: async () => {},
getTodoById: () => {},
updateTodoById: async () => {},
deleteTodoById: () => {},
};Мы просто экспортируем объект здесь с некоторыми именованными функциями, которые пустые (на данный момент).
Далее иди в свой файл Маршруты/Todo.ts И введите это:
import { Router } from "https://deno.land/x/oak/mod.ts";
const router = new Router();
// controller
import todoController from "../controllers/todo.ts";
router
.get("/todos", todoController.getAllTodos)
.post("/todos", todoController.createTodo)
.get("/todos/:id", todoController.getTodoById)
.put("/todos/:id", todoController.updateTodoById)
.delete("/todos/:id", todoController.deleteTodoById);
export default router;Это может выглядеть знакомы людям, которые работали с узлом и экспресс.
Все, что мы делаем здесь, импортируют Маршрут от дуб а затем создать новый экземпляр маршрутизатора, делая Const Router (); Отказ
Далее мы импортируем наши контроллеры, делая:
import todoController from "../controllers/todo.ts";
Здесь, в DENO, каждый раз, когда мы импортируем локальный файл в нашем проекте Deno, мы должны предоставить расширение файла. Это потому, что DENO не знает, является ли импортируемый файл .js или .ts файл.
Движение вперед Мы просто устанавливаем все наши маршруты в соответствии с конвенциями отдыха:
router
.get("/todos", todoController.getAllTodos)
.post("/todos", todoController.createTodo)
.get("/todos/:id", todoController.getTodoById)
.put("/todos/:id", todoController.updateTodoById)
.delete("/todos/:id", todoController.deleteTodoById);Код выше будет переводить на наше определение API, как это:
| ПОЛУЧАТЬ | / Тодос | |||
| ПОЛУЧАТЬ | / TODOS /: ID | |||
| ПОЧТА | / Тодос | |||
| ПОЛОЖИЛ | / TODOS /: ID | |||
| УДАЛЯТЬ | / TODOS /: ID |
И в конце мы просто экспортируем наш роутер, делая экспорт по умолчанию маршрутизатор; Отказ
Мы закончили с созданием структуры наших маршрутов. (Теперь каждый маршрут ничего не делает ничего, потому что наши контроллеры пусты, мы добавим функциональность для них немного.)
Вот последний кусок головоломки, прежде чем мы начнем добавить функциональность на каждый контроллер маршрута. Нам нужно приложить это Маршрутизатор нашему приложение пример.
Так что отправляйтесь на Server.ts файл и сделайте следующее:
- Добавьте это к самому топу:
// routes import todoRouter from "./routes/todo.ts";
- Удалить этот кусок кода:
const router = new Router();
router.get("/", ({ response }: { response: any }) => {
response.body = {
message: "hello world",
};
});
app.use(router.routes());
app.use(router.allowedMethods());- Замените его с помощью:
app.use(todoRouter.routes()); app.use(todoRouter.allowedMethods());
Это это – мы сделали. Ваш Server.ts Файл должен выглядеть так:
import { Application } from "https://deno.land/x/oak/mod.ts";
import { green, yellow } from "https://deno.land/std@0.53.0/fmt/colors.ts";
// routes
import todoRouter from "./routes/todo.ts";
const app = new Application();
const port: number = 8080;
app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());
app.addEventListener("listen", ({ secure, hostname, port }) => {
const protocol = secure ? "https://" : "http://";
const url = `${protocol}${hostname ?? "localhost"}:${port}`;
console.log(
`${yellow("Listening on:")} ${green(url)}`,
);
});
await app.listen({ port });
Если вы застряли в любом месте, следуя за этим, простая отправляется на исходный код этого учебника здесь Отказ
Удивительно, теперь у нас есть наши маршруты без функциональности в данный момент. Так что давайте добавим эту функциональность в наших контроллерах.
Но прежде чем мы сделаем это, мы должны создать еще 2 (крошечные) файлы.
- В вашей корневой папке создайте новую папку под названием
интерфейсыИ внутри этой папки создают файл под названиемTodo.ts(Убедитесь, что ToDo Captized, так как он не даст никакой синтаксической ошибки здесь, если вы этого не сделаете – это только конвенции.) - Также в вашей корневой папке создайте новую папку под названием
заглушкиИ внутри этой папки создают файл под названиемТодос.с.
Давайте создадим интерфейс в нашем Интерфейсы/todo.ts файл. Просто добавьте следующий код:
export default interface Todo {
id: string,
todo: string,
isCompleted: boolean,
}Что такое интерфейс?
Одним из основных вещей в TypeScript является проверка формы, которую имеет значение. Похоже на Порт-порт: или {Ответ}: {Ответ: любой} , мы также можем напечатать проверку объекта.
В типографии интерфейсы заполняют роль именования этих типов и являются мощным способом Определение договоров в пределах Ваш код, а также Контракты с кодом за пределами вашего проекта.
Вот еще один пример интерфейса:
// We have an interface
interface LabeledValue {
label: string;
}
// the arg passed to this function labeledObj is
// of type LabeledValue (interface)
function printLabel(labeledObj: LabeledValue) {
console.log(labeledObj.label);
}
let myObj = {label: "Size 10 Object"};
printLabel(myObj);Надеюсь, этот пример дает вам немного больше понимания интерфейсов. Если вы хотите более подробную информацию, проверьте документы на Интерфейсы здесь Отказ
Теперь, когда наш интерфейс готов, давайте посмотрим некоторые данные (поскольку у нас нет фактической базы данных для этого учебника).
Давайте сначала создадим список Mock ToDos в нашем заглушки/Тодос.тс файл. Просто добавьте следующее:
import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interface
import Todo from '../interfaces/Todo.ts';
let todos: Todo[] = [
{
id: v4.generate(),
todo: 'walk dog',
isCompleted: true,
},
{
id: v4.generate(),
todo: 'eat food',
isCompleted: false,
},
];
export default todos;- Две вещи, чтобы заметить здесь: мы добавляем новый пакет и используем его метод
v4Делая Импорт{v4}от"https://deno.land/std/uuid/mod.ts";Отказ Тогда каждый раз, когда мы используемv4.generate ()Это создаст новую случайную строкуIDОтказIDне может бытьНомер, толькоСтрокаПотому что в нашемTodoинтерфейс Мы определилиIDкак строка. - Другая вещь, чтобы сосредоточиться на вот –
Пустьтодос:Todo[]=[]. Это в основном говорит обозначать, что наш массив TODOS имеет типTodo(который потрясающий, наш компилятор сейчас автоматически знает, что каждый элемент в нашем массиве может иметь только{ID:String,ToDo:Строка&iscompleted:логический}Это не примет какой-либо другой ключ).
Если вы хотите узнать больше о интерфейсы В TeameStry Просмотрите эту удивительную подробную документацию на интерфейсах здесь Отказ
Потрясающие. Если вы пришли так далеко, дайте себе похлопывание на спину. Хорошая работа всем.
Давайте работать над нашими контроллерами
В вашем файле Контроллеры/TODO.TS :
export default {
getAllTodos: () => {},
createTodo: async () => {},
getTodoById: () => {},
updateTodoById: async () => {},
deleteTodoById: () => {},
};
Давайте напишем контроллер для Гетантодос :
// stubs
import todos from "../stubs/todos.ts";
export default {
/**
* @description Get all todos
* @route GET /todos
*/
getAllTodos: ({ response }: { response: any }) => {
response.status = 200;
response.body = {
success: true,
data: todos,
};
},
createTodo: async () => {},
getTodoById: () => {},
updateTodoById: async () => {},
deleteTodoById: () => {},
};
Прежде чем начать на этом блоке кода, позвольте мне объяснить, что каждый контроллер имеет аргумент – давайте назовем это контекст .
Итак, мы можем деконструировать getalltodos. : (контекст) = > {} к:
getAllTodos: ({ request, response, params }) => {}И так как мы используем машинопись Мы должны добавить тип проверки на все эти переменные:
getAllTodos: (
{ request, response, params }: {
request: any,
response: any,
params: { id: string },
},
) => {}Таким образом, мы добавили тип проверки на все 3 {запрос, ответ, параметры}
Запросэто то, что пользователь отправляет нам (информация, как заголовки и данные JSON)ответэто то, что мы отправляем пользователя обратно в ответ APIПармыЭто то, что мы определяем на наших маршрутах маршрутизатора, то есть:
.get("/todos/:id", ({ params}: { params: { id: string } }) => {})Итак, : id в /TODOS/: ID это параметр. Пармы – это способ получить информацию от URL. В этом примере мы знаем, что у нас есть /:я бы . Поэтому, когда пользователь пытается получить доступ к этой API (то есть /Todos/756 ) 756 в основном : id параметр Так как это в URL, мы знаем, что это типа нить .
Теперь, когда у нас есть определенные основные определения, давайте вернемся к нашему контроллеру Тодос:
// stubs
import todos from "../stubs/todos.ts";
export default {
/**
* @description Get all todos
* @route GET /todos
*/
getAllTodos: ({ response }: { response: any }) => {
response.status = 200;
response.body = {
success: true,
data: todos,
};
},
createTodo: async () => {},
getTodoById: () => {},
updateTodoById: async () => {},
deleteTodoById: () => {},
};
Для getalltodos. нам нужно только ответ Отказ Если вы помните, ответ это то, что нужно для отправки данных обратно пользователю.
Для людей, приходящих с узла и экспресс-фон, одна большая вещь, которая отличается вот то, что нам не нужно вернуть объект ответа. Deno делает это для нас автоматически.
Все, что нам нужно сделать, это установить Ответ .status Что в этом случае это 200 Отказ
Подробнее о статусах ответа здесь Отказ
Другое, что мы устанавливаем, это Ответ.body Что в этом случае является объектом:
{
success: true,
data: todos
}Я пойду вперед и запустим свой сервер:
$ deno run --allow-net server.ts
Как только ваш сервер работает, вы можете получить доступ к Получить/Тодос API. Я использую почтальон который является расширением Google Chrome и может быть загружено здесь Отказ
Вы можете использовать все, что вам нравится. Мне нравится использовать почтальон Потому что я думаю, что это очень легко.
В Postman откройте новую вкладку. Установите запрос на тип Получить и в URL тип бара http://localhost: 8080/Todos Отказ Хит Отправить И это то, что вы видите:
Прохладный! 1 API сделано, еще 4, чтобы пойти. ??
Если вы чувствуете себя застрявшему в любом месте, просто убирайте пик в исходном коде напрямую здесь Отказ
Давайте перейдем к нашему следующему контроллеру:
import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";
export default {
getAllTodos: () => {},
/**
* @description Add a new todo
* @route POST /todos
*/
createTodo: async (
{ request, response }: { request: any; response: any },
) => {
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}
// if everything is fine then perform
// operation and return todos with the
// new data added.
let newTodo: Todo = {
id: v4.generate(),
todo: body.value.todo,
isCompleted: false,
};
let data = [...todos, newTodo];
response.body = {
success: true,
data,
};
},
getTodoById: () => {},
updateTodoById: async () => {},
deleteTodoById: () => {},
};
Поскольку мы будем добавлять новый TOO в наш список, я импортировал 2 модуля в файле контроллера.
Импорт {v4} из `https://deno.land/std/uuid/mod.ts`;Это будет использоваться для создания нового уникального для созданного TODOИмпорт Todo из "../Interfaces/todo.ts";Это будет использоваться для обеспечения того, чтобы создавать новую тоду, которое следует за той же структурой.
Наше CreateTodo Контроллер – это async Смысл, что есть некоторые обещания, используемые внутри контроллера.
Давайте сломаемся на меньших частях:
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}Сначала мы получаем содержание тела JSON, которое пользователь отправил нас. Тогда мы используем Дуб Встроенный метод под названием request.hasbody Чтобы проверить, даже отправил пользователь любой контент. Если нет, то мы можем сделать Если (! Запрос . чесож) {} внутри этого Если блокировать.
Мы устанавливаем статус на 400 (400 означает, что пользователь сделал то, что они не должны были сделать), и тело установлено на {Успех: false, Сообщение: "Нет предоставленных данных} . Тогда мы просто добавьте возвращение; Чтобы гарантировать, что дополнительный код ниже не выполняется.
Далее мы сделаем это:
// if everything is fine then perform
// operation and return todos with the
// new data added.
let newTodo: Todo = {
id: v4.generate(),
todo: body.value.todo,
isCompleted: false,
};
let data = [...todos, newTodo];
response.body = {
success: true,
data,
};Мы создаем новый Todo, делая это:
let newTodo: Todo = {
id: v4.generate(),
todo: body.value.todo,
isCompleted: false,
};Пусть newtodo: todo = {} гарантирует, что Ньютодо следует той же структурой, что и остальная часть Тодоса. Затем мы назначаем случайный идентификатор, используя v4.generate () Установите ToDo в body.value.todo. а также iscompleted к ложь Отказ
Здесь следует заметить все данные, которые пользователь отправляет нас, мы можем получить доступ к body.value. в дуб .
Далее мы сделаем следующее:
let data = [...todos, newTodo];
response.body = {
success: true,
data,
};Добавить Ньютодо в наш текущий список TODOS и просто установите тело на {Успех: True & Data: Data Отказ
И мы делаем ✅ с этим контроллером.
Перезапустим наш сервер:
$ deno run --allow-net server.ts
В моем почтальоте я открываю новую вкладку. Установите запрос на Пост Тип и в URL тип бара http://localhost: 8080/Todos . Затем ударил Отправить И это то, что вы видите:
Затем я отправляю некоторое содержание в теле загрузки запроса и попробуйте еще раз:
Cool, мы видим, что наша API работает как ожидалось.
Два API вниз, еще три, чтобы пойти.
Мы почти на месте. Большая часть тяжелой работы сделана. ☺️? ? ?
Давайте перейдем к нашему третьему API:
import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";
export default {
getAllTodos: () => {},
createTodo: async () => {},
/**
* @description Get todo by id
* @route GET todos/:id
*/
getTodoById: (
{ params, response }: { params: { id: string }; response: any },
) => {
const todo: Todo | undefined = todos.find((t) => {
return t.id === params.id;
});
if (!todo) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
// If todo is found
response.status = 200;
response.body = {
success: true,
data: todo,
};
},
updateTodoById: async () => {},
deleteTodoById: () => {},
};
Давайте поговорим о нашем контроллере для Получить Тодос/: ID . Это приведет нас к ID.
Давайте сломаем это на меньшие части и обсудим это:
const todo: Todo | undefined = todos.find((t) => t.id === params.id);
if (!todo) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}В первой части мы устанавливаем новый Const Todo и установите его тип на Делать или undefined Отказ Итак, Todo будет либо объектом с Todo Форма интерфейса или это будет неопределенный – Это не может быть ничего другого.
Затем мы todos.find (( t ) => T.id === params.id ); использовать Array.find. () найти Todo с идентификатором в params.id Отказ Если это соответствует, мы получаем Todo С формой делать иначе undefined Отказ
Если Todo не определен, это означает, что это Если Блок будет работать:
if (!todo) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}Здесь мы просто устанавливаем статус на 404 что означает не найден наряду с нашей стандартной неудачей ответом или { статус }
Круто, верно? ?
Далее мы просто делаем это:
// If todo is found
response.status = 200;
response.body = {
success: true,
data: todo,
};Установите 200 Ответ успеха и в нашем отклике тела мы устанавливаем Успех: True & Data: Todo Отказ
Давайте запустим это в нашем почтенам.
Перезапустим наш сервер:
$ deno run --allow-net server.ts
В моем почтальоте я открываю новую вкладку. Установите запрос на Получить Тип и в URL тип бара http://localhost: 8080/TODOS/: ID Затем ударил Отправить Отказ
Поскольку мы генерируем ID случайным образом, сначала получите все TODOS, ударяя по титулю все API TODOS. Затем из любого Todo получают один из его удостоверений, чтобы проверить эту недавно созданную API. Каждый раз, когда вы перезапускаете это приложение DENO, будет сгенерирован новые идентификаторы.
Пойдем:
Если вам нужно ссылаться на исходный код исходного кода этого учебника Go здесь Отказ
Отлично, 3 apis сделали, еще 2, чтобы пойти.
import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";
export default {
getAllTodos: () => {},
createTodo: async () => {},
getTodoById: () => {},
/**
* @description Update todo by id
* @route PUT todos/:id
*/
updateTodoById: async (
{ params, request, response }: {
params: { id: string },
request: any,
response: any,
},
) => {
const todo: Todo | undefined = todos.find((t) => t.id === params.id);
if (!todo) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
// if todo found then update todo
const body = await request.body();
const updatedData: { todo?: string; isCompleted?: boolean } = body.value;
let newTodos = todos.map((t) => {
return t.id === params.id ? { ...t, ...updatedData } : t;
});
response.status = 200;
response.body = {
success: true,
data: newTodos,
};
},
deleteTodoById: () => {},
};
Давайте поговорим о нашем контроллере для Положите Тодос/: ID . Это обновит Todo по идентификатору.
Давайте сломаем это на меньшие биты:
const todo: Todo | undefined = todos.find((t) => t.id === params.id);
if (!todo) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}Это то, что мы сделали точно так же с предыдущим контроллером, поэтому я не буду уходить в значительную деталь здесь.
Pro Tip здесь: Вы можете, если хотите сделать этот кусок кода общий блок кода, а затем использовать его в обоих контроллерах.
Далее мы сделаем это:
// if todo found then update todo
const body = await request.body();
const updatedData: { todo?: string; isCompleted?: boolean } = body.value;
let newTodos = todos.map((t) => {
return t.id === params.id ? { ...t, ...updatedData } : t;
});
response.status = 200;
response.body = {
success: true,
data: newTodos,
};Кусок кода, о котором я хочу поговорить здесь, заключается в следующем:
const updatedData: { todo?: string; isCompleted?: boolean } = body.value;
let newTodos = todos.map((t) => {
return t.id === params.id ? { ...t, ...updatedData } : t;
});Сначала мы делаем Const.Value. а затем добавить тип проверки на UpdatedData Как следующее:
updatedData: { todo?: string; isCompleted?: boolean }Этот кусок кода говорит TS, что UpdatedData это объект, который может иметь/не иметь Todo: string и Также может иметь/не иметь iscompleted: Boolean.
Тогда мы просто карта по всему талому, как это:
let newTodos = todos.map((t) => {
return t.id === params.id ? { ...t, ...updatedData } : t;
});А где params.id Матч с T.ID Мы просто добавляем все на этот объект, который мы получаем от пользователя.
Мы также сделаем с этим API.
Перезапустим наш сервер:
$ deno run --allow-net server.ts
Откройте новую вкладку в Postman. Установите запрос на Поставить и в URL тип бара в http://localhost: 8080/TODOS/: ID Затем ударил Отправить :
Поскольку мы генерируем ID случайным образом, сначала получите все TODOS, ударив все TODOS API. Затем из любого Todo получают один из его удостоверений, чтобы проверить эту недавно созданную API. Каждый раз, когда вы перезапускаете это приложение DENO, будет сгенерирован новые идентификаторы.
Это удивительно – четыре API и еще один, чтобы пойти.
import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";
export default {
getAllTodos: () => {},
createTodo: async () => {},
getTodoById: () => {},
updateTodoById: async () => {},
/**
* @description Delete todo by id
* @route DELETE todos/:id
*/
deleteTodoById: (
{ params, response }: { params: { id: string }; response: any },
) => {
const allTodos = todos.filter((t) => t.id !== params.id);
// remove the todo w.r.t id and return
// remaining todos
response.status = 200;
response.body = {
success: true,
data: allTodos,
};
},
};
Давайте поговорим о нашем контроллере для Удалить TODOS/: ID Это удалит TODO по идентификатору.
Мы просто запускаем фильтр во всех Todos:
const allTodos = todos.filter((t) => t.id !== params.id);
Удалить todo.id это соответствует params.id и вернуть остальные.
Тогда мы делаем это:
// remove the todo w.r.t id and return
// remaining todos
response.status = 200;
response.body = {
success: true,
data: allTodos,
};Просто верните все оставленные тодос, которые не имеют одинакового toDo.id.
Перезапустим наш сервер:
$ deno run --allow-net server.ts
Откройте новую вкладку в Postman. На этот раз установите запрос на Удалить и в URL тип бара http://localhost: 8080/TODOS/: ID и ударил Отправить Отказ
Поскольку мы генерируем ID случайным образом, сначала получите все TODOS, ударив все TODOS API. Затем из любого Todo получают один из его удостоверений, чтобы проверить эту недавно созданную API. Каждый раз, когда вы перезапускаете это приложение DENO, будет сгенерирован новые идентификаторы.
С этим мы все сделаем со всеми пятью API.
Теперь у нас есть только две вещи:
- Добавьте не найденное маршрута промежуточного программного обеспечения так, что когда пользователь пытается получить доступ к неизвестному маршруту, он дает ошибку.
- Добавьте API Logger, который усаживает время отклика, которое потребовалось для возврата данных с одной конечной точки API.
Создание промежуточного программного обеспечения маршрута для маршрутов это не найдено
В вашей корневой папке создайте новую папку под названием средние годы Отказ Внутри этой папки создают файл под названием Notfound.ts И внутри этого файла добавьте этот код:
export default ({ response }: { response: any }) => {
response.status = 404;
response.body = {
success: false,
message: "404 - Not found.",
};
};
Здесь мы не делаем ничего нового – это очень похоже на структуру наших контроллеров. Просто вернув статус 404 (что означает не найден) вместе с объектом JSON для {Успех, Сообщение} Отказ
Далее иди в свой Server.ts Файл и добавьте следующий контент:
- Добавьте этот импорт где-то наверху:
// not found import notFound from './middlewares/notFound.ts';
- А затем чуть ниже вашего
app.use (todorouter.allowedmethods ())Добавьте эту строку, как это:
app.use(todoRouter.routes()); app.use(todoRouter.allowedMethods()); // 404 page app.use(notFound);
Распоряжение выполнения важно здесь: каждый раз, когда мы пытаемся получить доступ к конечной точке API, он сначала будет соответствовать/проверить маршруты из наших Тодорутер Отказ Если никто не найден, он будет выполнять приложение .использовать (не найден); .
Давайте посмотрим, если это работает.
Перезагрузите сервер:
$ deno run --allow-net server.ts
Откройте новую вкладку в Postman. Установите запрос на Получить и в URL тип бара http://localhost: 8080/что-то-неизвестное Затем ударил Отправить Отказ
Таким образом, у нас теперь есть промежуточное программное обеспечение маршрута, которое мы помещаем в конце наших маршрутов в Server.ts как приложение .использовать (не найден); . Если маршрут не совпадает с этим промежуточным программным обеспечением, он выполнит и вернет 404 код состояния (что означает не найден). Тогда мы просто отправляем сообщение о ответе, как всегда, который является {Успех, Сообщение} Отказ
Pro Tip: Мы решили, что {Успех, Сообщение} Это то, что мы возвращаем в неудачные сценарии и {Успех, Данные} Это то, что мы возвращаемся к пользователю в сценариях успеха. Таким образом, мы даже можем сделать это объектом/формам в качестве интерфейсов и добавлять их в наш проект, чтобы обеспечить проверку согласованности и безопасного типа.
Cool, теперь мы сделаем с одним из наших подразгоний – давайте добавим другое промежуточное программное обеспечение для регистрации наших API в консоли.
Напоминание: Если вы застряли где-нибудь, вы можете использовать Исходный код здесь Отказ
Регистрация API в консоли
В вашем средние годы Папка создает новый файл под названием logger.ts и введите следующий код:
import {
green,
cyan,
white,
bgRed,
} from "https://deno.land/std@0.53.0/fmt/colors.ts";
const X_RESPONSE_TIME: string = "X-Response-Time";
export default {
logger: async (
{ response, request }: { response: any, request: any },
next: Function,
) => {
await next();
const responseTime = response.headers.get(X_RESPONSE_TIME);
console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
console.log(`${bgRed(white(String(responseTime)))}`);
},
responseTime: async (
{ response }: { response: any },
next: Function,
) => {
const start = Date.now();
await next();
const ms: number = Date.now() - start;
response.headers.set(X_RESPONSE_TIME, `${ms}ms`)
},
};
В вашем Server.ts Файл Добавить этот код:
- Импортируйте это где-то наверху:
// logger import logger from './middlewares/logger.ts';
- Чуть выше вашего
ТодорутерКод добавить эти подразнения, как это:
// order of execution is important; app.use(logger.logger); app.use(logger.responseTime); app.use(todoRouter.routes()); app.use(todoRouter.allowedMethods());
Теперь давайте обсудим то, что мы только что сделали.
Давайте поговорим о logger.ts Файл и разбить его в биты:
import {
green,
cyan,
white,
bgRed,
} from "https://deno.land/std@0.53.0/fmt/colors.ts";Я импортирую некоторые цвета консоли и консольные цвета фона, которые я хочу использовать в журнале API.
Это похоже на то, что мы сделали в нашем EventListener В нашем Server.ts файл. Мы будем использовать цвета в нашей консоли для записи запросов API.
Далее я устанавливаю const x_response_time:;; Отказ Это заголовок, который мы вводим в наших запросах API, когда они приходят на наш сервер. Я называю это X_response_time. и его значение – X-отклика - время Отказ Я буду продемонстрировать его использование немного.
Далее мы просто экспортируем такой объект:
export default {
logger: async ({ response, request }, next) {}
responseTime: async ({ response }, next) {}
};И тогда мы просто используем его внутри нашего Server.ts файл, как это:
// order of execution is important; app.use(logger.logger); app.use(logger.responseTime);
Давайте теперь обсудим, что происходит в нашем промежуточном коде Mogger и обсудить его в стиле исполнения, используя Далее () :
Единственная разница здесь и в контроллерах у нас было раньше, это использование Далее () функция. Эта функция помогает нам перейти от одного контроллера на другой, как показано на рисунке ниже.
Так в:
export default {
logger: async (
{ response, request }: { response: any, request: any },
next: Function,
) => {
await next();
const responseTime = response.headers.get(X_RESPONSE_TIME);
console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
console.log(`${bgRed(white(String(responseTime)))}`);
},
responseTime: async (
{ response }: { response: any },
next: Function,
) => {
const start = Date.now();
await next();
const ms: number = Date.now() - start;
response.headers.set(X_RESPONSE_TIME, `${ms}ms`)
},
};Имейте в виду, что это то, что у нас есть в нашем Server.ts файл:
// order of execution is important; app.use(logger.logger); app.use(logger.responseTime); app.use(todoRouter.routes()); app.use(todoRouter.allowedMethods());
Порядок выполнения выглядит следующим образом:
- logger.logger промежуточное программное обеспечение
- logger.responsetime промежуточное программное обеспечение
- Контроллер Todorouter (любой путь вызывается пользователем, с целью объяснения, я предполагаю, что пользователь под названием
Get/ToDosAPI, чтобы получить все Тодос.)
Так что сначала будет выполнять logger.logger промежуточное программное обеспечение, которое это:
logger: async (
{ response, request }: { response: any, request: any },
next: Function,
) => {
await next();
const responseTime = response.headers.get(X_RESPONSE_TIME);
console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
console.log(`${bgRed(white(String(responseTime)))}`);
},Это придет в эту функцию и сразу же, как он читает жду следующего () Это быстро прыгает на следующую промежуточное программное обеспечение, которое является время отклика :
Внутри Отдых на работу , это только выполняет две линии, которые являются (посмотрите на выполнение заказа 2 в изображении выше):
const start = Date.now(); await next();
Перед прыжками на Гетантодос контроллер. Как только это идет внутри getalltodos. Он запускает весь код внутри этого контроллера.
Так как в этом контроллере мы не используем Далее () Это просто вернет поток логики обратно в Отдых на работу контроллер. Там он будет запускать следующее:
const ms: number = Date.now() - start;
response.headers.set(X_RESPONSE_TIME, `${ms}ms`)Теперь сохраняясь в перспективе порядка исполнения, которое является 2, 3, 4 (Посмотрите на изображение выше).
Это то, что происходит:
- Мы захватываем данные в
MSДелаяConstНачать=Дата. Теперь();Отказ Тогда мы сразу звонимДалее ()который идет вГетантодосконтроллер и запускает весь код. Тогда это возвращается вОтдых на работуконтроллер. - Затем мы вычвеем, что
НачатьДата любую дату в тот момент, делаяконститутРС:Номер=Дата()-Начать;РС. Здесь это вернет номер, который в основном разница в миллисекундах, которые расскажут нам все время, чтобы разному было выполнить нашиГетантодосконтроллер.
Разделение изображения еще раз для обзора:
- Далее мы просто устанавливаем заголовки в нашем
ответнравится:
response.headers.set(X_RESPONSE_TIME, `${ms}ms`)Который просто устанавливает значение заголовка X-отклика - время Для миллисекунды потребовалось deno для выполнения нашего API.
- Тогда от исполнения Заказать
4Мы вернемся к исполнению Заказать5(Посмотрите на изображение выше для справки).
Здесь мы просто делаем:
const responseTime = response.headers.get(X_RESPONSE_TIME);
console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
console.log(`${bgRed(white(String(responseTime)))}`);- Мы получаем время, которое мы прошли в
X-Отклика - время - Затем мы берем это время и просто утешайте его красочно в консоли.
request.method Рассказывает нам метод, используемый для нашего API, то есть Получить, положить и т. Д. в то время как request.url.Pathname скажу API, какой путь пользователь использовал i.e, /Тодос
Давайте посмотрим, если это работает.
Перезагрузите сервер:
$ deno run --allow-net server.ts
Откройте новую вкладку в Postman. Установите запрос на Получить , введите http://localhost: 8080/Todos и ударил Отправить Отказ
Нажмите API пару раз в почтальон. Затем, когда вы вернетесь к консоли, вы должны увидеть что-то вроде этого:
Это это – мы сделали.
Если вы все еще чувствуете себя застрявшим, посмотрите на весь исходный код для этого руководства здесь: github.com/adeelibr/deno-playground/tree/master/chapter_1:oak
Я надеюсь, что вы нашли эту статью полезную, и что она смогла помочь вам узнать что-то сегодня.
Если вам это понравилось, пожалуйста, поделитесь им в социальных сетях. Если вы хотите обсудить об этом, обратитесь к мне на Twitter Отказ
Оригинал: “https://www.freecodecamp.org/news/create-a-todo-api-in-deno-written-by-a-guy-coming-from-node/”