Очередной чат, и к тому же на rust?! Да, yet another. И да, в этой статье не будет каких-то новых откровений системного программирования с написанием своего фреймворка для работы со сетью на уровне драйверов или других испытаний. Этот альманах про мой первый опыт в веб-разработке, который может быть полезен для других новичков, ведь тут мы затронем помимо злосчастного rust такие вещи, как devcontainer, REST API, идентификацию-аунтификацию-авторизацию, WebSockets, SSE, юнит и интеграционные тесты, некоторые паттерны, логирование и прочее.
Выберем каким редактором кода будем пользоваться. Это довольно холиварная тема, но я остановлюсь на VS Code по таким причинам, как он лёгок в настройке, довольно шустрый, есть гибкие профили и дебаг-конфиги, синхронизация настроек, куча плагинов на любой вкус и цвет, кроссплатформенный. А ещё он умеет в devcontainer, но об этом чуть позже.
Весь проект будет находиться в монорепозитории на github. Это довольно удобно, особенно когда изменения вносятся сразу в нескольких местах, не приходится делать несколько пулл реквестов, и не забываешь подгрузить сабмодули. Это всё, конечно, хорошо, но усложняет последующий CI/CD. Чтобы как-то облегчить себе работу по слежке за версиями, будем использовать conventional commit.
Так как сервер будет написан на rust, то нам нужен и соответствующий тулчейн, который требует, помимо прочего, ещё и установить зависимости в виде Visual Studio в Windows. А потом ещё и потребуется развернуть базу данных и/или Redis. И ладно, если вы один работаете над своим pet-проектом, но представьте, что работаете сразу на нескольких тачках, как и я, или с вами работают другие люди, то проблем с тем, что развернуть набор инструментов с теми же настройками, не избежать. Или просто не хотите захламлять систему лишним. Для целей развёртки инфраструктуры разработки силами Microsoft был придуман devcontainer, который базируется на технологиях контейнеризации Docker.
Сильными сторонами devcontainer можно считать абсолютную простоту в использовании, если хотя бы пару раз трогали траву Dockerfile и docker-compose. Из минусов очевидный оверхед из-за виртуализации, который даёт достаточно сильное влияние на скорость рабочих процессов, включая анализ и компиляцию кода.
Давайте начнём, создав папку server, в которую положим файл .devcontainer.json, со следующим содержимым:
{
"name": "rust-devcontainer",
"image": "mcr.microsoft.com/devcontainers/rust:latest"
}
Всё, на этом вся настройка devcontainer завершена, можно смело открывать эту папку в VS Code, после чего он сам увидит файл и предложит установить соответствующий плагин, который, в свою очередь, скачает образ и запустит контейнер. Если вам нужен не rust-тулчейн, а какой-нибудь, например, .NET, то можете посмотреть либо на странице Templates, либо в регистре Microsoft. Помимо прочего, есть базовый образ, который позволит легко создать своё окружение.
Помимо готовых шаблонов, devcontainer башляет настройками редактора, можно установить единые для всех плагины, которые будут работать внутри контейнера, и настройки редактора. Как пример, давайте добавим плагины для работы с базой и переопределим для работы nightly версии rustfmt. Для этого нужно указать поле customizations в файле .devcontainer.json.
{
"name": "rust-devcontainer",
"image": "mcr.microsoft.com/devcontainers/rust:latest",
"customizations": {
"vscode": {
"extensions": [
"ms-ossdata.vscode-pgsql",
],
"settings": {
"rust-analyzer.rustfmt.overrideCommand": ["rustfmt", "+nightly", "--edition", "2024"]
}
}
}
}
Если речь зашла об nightly версии rustfmt, то давайте покажу, как добавить эту версию в окружение. Для этого нам придётся создать папку devcontainer (хотя можете и без неё) и переместить в неё файл .devcontainer.json, после чего создать файл Dockerfile со следующим содержимым:
FROM mcr.microsoft.com/devcontainers/rust:latest
RUN rustup component add --toolchain nightly-x86_64-unknown-linux-gnu rustfmt
Первая строчка говорит о том, что мы будем использовать готовый образ как отправную точку, после чего добавляем нужный нам компонент rustfmt. Чтобы devcontainer начал использовать наш Dockerfile, нужно заменить поле image в .devcontainer.json на build со следующими полями:
{
"name": "rust-devcontainer",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"customizations": {
"vscode": {
"extensions": [
"ms-ossdata.vscode-pgsql",
],
"settings": {
"rust-analyzer.rustfmt.overrideCommand": ["rustfmt", "+nightly", "--edition", "2024"]
}
}
}
}
Оба этих поля указываются относительно файла .devcontainer.json, так как Dockerfile лежит в той же директории, то мы просто указываем его название. Поле context указывает, что будет копироваться внутрь контейнера.
Помимо прочего, можно использовать docker-compose. Для примера создим в той же директории файл docker-compose.yml со следующим содержимым: