Сокращатели URL-адресов — это отличный способ сделать веб-ссылки более презентабельными, короткими и удобными для обмена. В этом порту мы научимся создавать его с нуля!

Примечания

Вы можете найти окончательный исходный код на raymag/shmag. На этом сайте также работает URL Shortener, вы можете протестировать его на свое усмотрение.

Кстати, если вы собираетесь следовать этому руководству и хотите воспроизвести его на своем компьютере (что лучше всего), вам необходимо установить NodeJS.

Я также рекомендую вам иметь клиент REST, такой как Postman или Insomnia, для тестирования маршрутов API.

Планирование

Хорошо, мы собираемся создать API сокращения URL. Но как мы это делаем?

Ну, есть несколько способов решить эту проблему, но способ, который мы собираемся использовать, довольно прост.

  • Пользователь собирается передать URL, которое он хочет сократить, API возьмет это URL, сгенерирует для него случайный alias и сохранит их оба в базе данных.
  • Когда пользователь вызывает API, передавая этот alias в качестве параметра, API находит соответствующий URL в базе данных и перенаправляет пользователя на этот URL.

Настройка

Прежде всего, нам нужно настроить нашу среду. Я собираюсь создать новую папку для проекта, открыть в ней свой терминал и запустить проект node с:

npm init -y

Поскольку наш проект запущен, давайте установим несколько крутых пакетов, которые нам понадобятся.

npm install express mongoose yup dotenv nanoid cors

О, мы также устанавливаем nodemon в качестве зависимости от разработчиков, чтобы облегчить себе жизнь.

npm install --save-dev nodemon

Итак, для чего мы будем использовать все эти пакеты? Ну и вкратце:

  • Express: он предоставит нам методы для обработки HTTP-запросов.
  • mongoose: мы собираемся использовать его для подключения к базе данных (да, у нас тоже будет база данных).
  • dotenv: это поможет нам обрабатывать конфиденциальные данные, такие как токены и URI базы данных.
  • yup: да, мы будем использовать его для проверки некоторых крутых параметров.
  • nanoid: так мы собираемся генерировать короткие версии URL-адресов.
  • cors: это поможет нам справиться с общим доступом к ресурсам между источниками.

Архитектура MVC

Для этого урока мы будем использовать архитектуру MVC, но без представлений в ней. Если вы не знакомы с шаблоном MVC, не волнуйтесь, потому что я дам вам простое объяснение, что это такое. Тем не менее, я предлагаю вам провести некоторые внешние исследования, чтобы дополнить ваши знания и навыки.

Объяснение архитектуры MVC

Короче говоря, MVC означает модель, представление и контроллеры. Это шаблон проектирования, который делит приложение на три части:

  • Вид: здесь находятся пользовательские интерфейсы. Таким образом, в основном пользовательские интерфейсы здесь называются представлениями.
  • Модель: это представления объектов базы данных. Например, пользователь может быть моделью во многих приложениях.
  • Контроллеры. Они являются посредниками/мостами между представлениями и моделями.

Когда мы делаем это разделение задач в разработке программного обеспечения, становится намного проще поддерживать, понимать и разрабатывать.

В случае MVC пользователь взаимодействует с пользовательским интерфейсом, которым является представление, затем представление связывается с контроллером, который будет вызывать модель. Затем модель передает данные базы данных контроллеру, который будет манипулировать ими, чтобы они были презентабельны для пользователя, и, наконец, контроллер передает их представлению, которое будет отображать все это в пользовательском интерфейсе.

Структура папок

Теперь, когда мы убедились, что вы знакомы с концепцией архитектуры MVC, мы можем начать работать с нашей файловой структурой, чтобы не запутаться, когда мы действительно начнем программировать материал.

Итак, имея в виду концепцию моделей, представлений и контроллеров, вот как будет выглядеть наша структура папок:

.
+-- node_modules/
+-- src/
|   +-- controllers/
|   +-- models/
|   +-- database/
+-- package.json
+-- package-lock.json

Настройка файла пакета

В файле package.json мы изменим поле «main» с «index.js» на «src/server.js». Это будет наш входной файл.

Мы также собираемся добавить несколько скриптов. Вот как это должно выглядеть:

Файл сервера

Хватит болтать, приступим к кодированию! Внутри папки src создайте новый файл с именем server.js. Это файл точки входа и место, где будет располагаться сервер.

А пока мы собираемся настроить самый простой HTTP-сервер, какой только сможем, поэтому server.js будет выглядеть так:

Этот код настраивает для нас простой сервер, поэтому, если вы хотите протестировать его, вы можете запустить npm run dev на терминале и открыть браузер с помощью localhost:3000.

Файл маршрутов

Хорошо, теперь, когда у нас запущен простой сервер, пришло время создать скрипт маршрутов. Это файл, в котором мы собираемся настроить все маршруты для нашего URL Shortener API.

Содержимое routes.js должно быть примерно таким:

Этот код просто импортирует метод Router из ExpressJS, определяет несколько маршрутов и в конце экспортирует их все. Обратите внимание, что я пока оставил два пустых маршрута. Они нам понадобятся позже.

Теперь мы можем обновить наш файл server.js и заставить его использовать маршруты, определенные в этом файле.

Итак, вот наш обновленный файл server.js:

Это по существу заканчивает server.js.

Если вы спрашиваете себя, почему маршруты отделены от файла сервера, это потому, что это упрощает отладку и понимание кода. Если вы сейчас посмотрите на server.js или routes.js, вы поймете, что код намного читается проще. Вы заглядываете в routes.js и сразу же понимаете, что это файл, который определяет все маршруты API. Этот способ намного более интуитивно понятен.

Написание моделей

Я думаю, пришло время начать работать над нашими моделями. Как я уже говорил, модели представляют собой представление/абстракцию объекта базы данных.

Однако нашему приложению нужна только одна сущность, что также означает, что ему нужна только 1 модель: модель ShortUrl.

С учетом сказанного создайте новый файл с именем ShortUrl.js внутри папки Model и откройте его в своей любимой среде IDE.

Хорошо, давайте объясним, что происходит. База данных, которую мы собираемся использовать для этого проекта, — MongoDB, и именно поэтому мы установили mongoose в первую очередь.

Чтобы создать модель объекта базы данных, вам сначала нужно создать схему этого объекта. Это похоже на план, описывающий, какие поля и значения имеет сущность. По сути, это то, что мы делаем с помощью метода mongoose.Schema().

Как я уже говорил, нашей сущности ShortUrl нужны только два значения: alias и исходное url. url — это строка, и она обязательна, но не обязательно должна быть уникальной (это означало бы, что она не может повторяться в базе данных), однако alias также является строкой, обязательным полем, но должно быть уникальным. Вот почему мы позаботились о том, чтобы с unique:true.

В конце кода мы экспортируем схему ShortUrl как файл model.

Настройка базы данных

В этом проекте мы используем MongoDB для базы данных. На данный момент у вас есть два варианта решения этой проблемы: вы можете либо установить MongoDB Community Server и хранить базу данных локально, либо использовать облачную базу данных, такую ​​как MongoDB Atlas (которая дает вам бесплатную простую базу данных-песочницу).

После того, как вы настроите базу данных, вам понадобится строка URI базы данных, которая имеет формат, аналогичный mongodb://<username>:<password>@host:port/<defaultdb>. Это то, что вам нужно для подключения к базе данных.

Если вы используете локальный сервер, строка URI по умолчанию — mongodb://localhost:27017, вы также можете передать базу данных по умолчанию, например: mongodb://localhost:27017/urlshortener.

Теперь, если вы используете облачную базу данных, найдите методы подключения, и они должны предоставить вам строку URI.

Файл Dotenv

Хорошо, у нас есть database connection URI string. Но это конфиденциальные данные, и они должны быть четко записаны в наших скриптах. Это было бы слишком рискованно и небезопасно.

Итак, чтобы сделать вещи более безопасными, мы собираемся поместить эту строку URI в файл .env. Затем мы собираемся использовать пакет dotenv для импорта данных в файл .env как переменные среды.

Таким образом, если вы хотите загрузить проект, например, в облако или в репозиторий github, вам также не нужно загружать файл .env.

Хватит говорить, давайте создадим новый файл с именем .env в корне нашего проекта. Внутри него напишите:

MONGODB_URI=mongodb://localhost:27017/urlshortener

Вы можете заменить строку URI на строку URI для вашей базы данных.

Подключение к базе данных

Теперь, когда мы настроили нашу базу данных и получили строку URI в файле .env, мы собираемся также создать новый скрипт для обработки подключения к базе данных.

Итак, создайте новый файл с именем index.js внутри папки database и откройте его в IDE.

По сути, мы импортируем пакет mongoose, вызывая метод dotenv config(), чтобы мы могли импортировать нашу переменную MONGODB_URI, определенную в .env, в скрипт, создавая асинхронную функцию для возврата соединения с базой данных и экспортируя ее.

Вам не нужно слишком беспокоиться о другом параметре, который мы передаем методу mongoose.connect(), потому что они необходимы только из-за устаревания некоторых внутренних методов мангуста.

Теперь мы можем вызвать эту функцию внутри нашего файла server.js.

Написание контроллеров

Теперь, когда наша база данных настроена, мы напишем код нашего контроллера. Я сказал controller вместо controllers, потому что нам понадобится только 1 из них. Этот контроллер позаботится о двух маршрутах, о которых мы заботимся.

Так что создайте новый файл с именем ShortUrlController.js внутри папки controllers и давайте писать код!

Вы уже знаете, что контроллеры — это что-то вроде моста между моделью и представлением. Это означает, что ShortUrlController будет иметь 2 метода для обработки наших 2 маршрутов. Мы вызываем один метод redirect, а другой store. Мы объявили и экспортировали их, но пока не будем кодировать их функциональность.

Обновление route.js

Теперь вернемся к нашему файлу routes.js и передадим методы ShortUrlController в качестве обработчиков маршрутов.

Посмотрите, насколько наш код стал намного чище. Легко понять, для чего нужны эти маршруты, даже не зная «особенностей» ShortUrlController. Это сила Concerns Separation и MVC.

Теперь мы можем начать работать над методами нашего контроллера.

Способ хранения

Сначала мы побеспокоимся о нашем методе store.

Ладно, теперь нам есть что рассказать. С самого начала мы импортировали пакеты nanoid и yup.

Я уже говорил вам, что yup — это пакет, который позволяет нам легко проверять объекты. В нашем случае мы собираемся использовать его, чтобы увидеть, использует ли Пользователь правильные параметры. Например, если это действительный URL-адрес и действительный псевдоним.

Это именно то, что мы сделали с:

В этом случае newUrlSchema — это схема параметров, которые мы ожидаем от пользователя.

Перейдем к самому методу store.

  • Мы получили параметры из запроса.
  • Подтвердил их с помощью нашего newUrlSchema.
  • Проверено, был ли также отправлен параметр alias
  • Если он не был отправлен, мы генерируем случайный, используя nanoid(5).
  • Если он был отправлен, мы проверяем, используется ли уже псевдоним. Мы сделали это с помощью ShortUrl.findOne({alias}), который использует нашу модель для поиска соответствующего псевдонима в базе данных.
  • Если он существует, будет выброшена ошибка.
  • в противном случае этот сокращенный URL-адрес будет сохранен в базе данных с ShortUrl.create(newShortUrl). Затем мы возвращаем данные базы данных на запрос в качестве ответа.

На этом этапе вы можете протестировать этот маршрут с помощью REST-клиента, такого как Insomnia или Postman (в моем случае я использую Insomnia):

Обратите внимание, что я передал URL своего веб-сайта в качестве параметра и получил взамен псевдоним lefid.

Метод перенаправления

Теперь давайте закодируем redirect method, что, если честно, довольно просто.

Вот как будет выглядеть redirect:

Все, что мы сделали, это:

  • Получите alias в качестве параметра URL (это означает, что мы передаем его как urlshortener.io/:alias).
  • Проверьте, соответствует ли этот псевдоним url в базе данных.
  • Если это так, мы перенаправляем запрос на этот matching url.
  • если нет, мы отправляем статус 404 с сообщением invalid url.

Наконец, вы также можете протестировать этот маршрут, будь то в браузере или внутри REST-клиента. В моем случае я собираюсь протестировать этот маршрут и с бессонницей.

В прошлый раз у меня был псевдоним lefid для моего сайта. Теперь, когда я передаю этот псевдоним в запросе GET, знаете что? Меня фактически перенаправляют на мой веб-сайт. Отлично!

Вывод

Хорошо, после всех этих шагов мы закончили наш API Shortener URL. Вы можете протестировать его прямо сейчас и развернуть в облаке! Поздравляю!

Как я уже говорил, вы можете проверить работу этого API за веб-сайтом здесь.

Если вы нашли слова с ошибками или другие мои ошибки, свяжитесь со мной или оставьте комментарий, чтобы я мог исправить это позже.

Кроме того, если у вас есть какие-либо предложения или что-то, что я должен добавить/изменить, я был бы рад узнать ваше мнение.

Хорошего дня!