Разработка курсового проекта «Gpxies.ru» для RSSchool
Участники разработки проекта
Минкевич Николай. Узнал о RSSchool от сотрудника EPAM. Выполнил все проекты, представленные на курсе, ментор Константин Шаврин. Главные сложности в прохождении курса были, в основном, в заданиях, связанных с вёрсткой. На задании «Презентация» выступал с рассказом о фреймворке Electron.
Васенина Анастасия. Узнала о RSSchool от Николая. Выполнила все проекты, представленные на курсе. Главной сложностью оказалось неудачное прохождение собеседования с потенциальным ментором. Но, несмотря на отсутвие наставника, Анастасия решила продолжить обучение самостоятельно, выполнила все последующие задания курса и успешно прошла собеседование JS Core.
Описание проекта
Gpxies.ru является приложением для загрузки, хранения и просмотра треков из gpx-файлов. Эти файлы формата GPS eXchange Format, основанного на XML, созданного для хранения данных GPS. Их можно встретить на навигационных устройствах (например, туристский навигатор или фитнес-трекер с GPS), также они широко используются мобильными приложениями, связанными с GPS (одни из самых популярных: Strava, Osmand для Андроида).
Основные возможности
После регистрации вы попадаете на страницу с таблицей ваших треков. Сразу после регистрации, их, разумеется, нет, но вы можете загрузить их на странице загрузки. Навигация осуществляется через меню сверху.

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

На странице загрузки трека вы можете загрузить gpx-файл (примеры gpx-файлов, которые можно использовать для проверки выложены тут), ввести название, тип тренировки, описание трека, указать его приватность.

Вы не сможете отправить трек без загруженного gpx-файла, так как это является основным функционалом данной страницы.
Для избежания случайного создания строки в таблице трека, для которого не был загружен gpx-файл, кнопка загрузки остается недоступной до момента загрузки файла.
В случае, если пользователь загрузил файл, но не ввел название, описание и не указал статус приватности, автоматически создается публичный трек с названием, состоящим из строки New track и даты загрузки файла.

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

Вы можете отсортировать их по названию, дате загрузки и по дистанции. Так же вы можете отфильтровать треки по виду спорта или по строке в названии.
При клике по названию трека вы перейдете на страницу просмотра трека. На странице показа вы можете удалить или скачать трек.

Эти же возможности есть и на странице с таблицей всех треков. Вы можете удалить или скачать один трек, или несколько, если отметите галочкой чекбокс в самой левой ячейке строки одного или нескольких треков.

При этом в правой верхней части таблицы появится меню с двумя кнопками: удалить и скачать. Этим меню удобно пользоваться, если вы хотите произвести одну из озвученных выше операций для нескольких треков.
После нажатия на кнопку “удалить” пользователь видит модальное меню с сообщением о успешном удалении, либо о незавершенном удалении. В обоих случаях пользователь может вернуться к списку треков, нажав на кнопку в модальном меню, либо кликнув мышью вне на экран него. Подобным образом работают все модальные окна в приложении.
Организация командной работы
Изначально перед нами стояло две глобальные задачи: нам нужно было создать серверную часть приложения (бэкэнд), для работы с базой данных (за эту часть работы отвечал Николай), а так же нужно было создать интерфейс, придумать и осуществить логику его работы (этим занималась Анастасия). В процессе работы это разделение не оставалось жестко зафиксированным. Кроме того, по завершению работы над бэкэндом, Николай присоеденился к разработке фронтенда приложения.

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

Для координации совместной работы использовалось приложение Trello. Сначала каждый участник создавал задания. Если в процессе разработки появлялись проблемы, каждый участник мог сформулировать эту проблему в качестве задания, и записать ее в таблицу Trello. Мы оценили возможность не хранить в своей памяти то, что нужно сделать, и не прерывать процесс разработки ради проблемы, решение которой можно отложить на какое-то время.
Когда разработчик заканчивал свою текущую задачу, он открывал таблицу Trello и смотрел, какие задачи требуется выполнить. Далее советовался со вторым разработчиком, и приступал к работе.
Архитектура проекта, особенности реализации
До начала разработки мы провели совещание, на котором определили технический стек разработки. Для разработки фронтенда было решено использовать HTML, CSS и чистый Javascript. Насчет последнего инструмента было немало сомнений, но все же мы решили не заменять его на React. Во время обучения во всех проектах использовался именно Javascript, поэтому, для закрепления полученных знаний, и для возможности переиспользования наработок, накопленных за время прохождения курса, React было решено оставить на будущее. Уже в ходе работы, пришлось решать задачи, которых не возникло бы при использовании фреймворка (например, осуществлять роутинг с авторизацией). К счастью, мы нашли способы для решения этих задач.
Описание стека технологий
Итак, стек технологий для фронтенда выглядит так: NodeJS+Express для роутинга, Webpack для разделения приложения на модули и сборки, Leaflet для работы с картой.
Для бекенда: NodeJS+Express для реализации обработки REST-запросов, JSONWebToken (JWT) для авторизации, MySQL2 для подключения к БД, Fast XML Parser для работы с загружаемыми файлами.
Для создания DOM-дерева была использована утилита create(). Она принимает в качестве аргументов тип DOM-узла, его класс, дочерние элементы, родительский элемент, в который он будет встроен, и атрибуты. Впервые эта утилита была использовала в задании Virtual keyboard. Ее идея и основная реализация пренадлежат автору видео, мы ему благодарны.
Эту функцию использовали, прежде всего, для решения проблемы с созданием DOM-узлов. Для того, чтобы создать DOM-узел на чистом JS, нужно отдельно создать этот узел, следующим действием добавить к нему класс, потом дочерние элементы, потом добавить атрибут и т.д. При использовании create() мы все эти операции можем объединить в одну. Это не значит, что мы не пользовались стандартными методами JS работы с DOM, но, все же, значительный объем работы удалось сократить. Этих проблем удалось бы избежать, если бы мы использовали React. Благодаря JSX разработка DOM-узлов в этом фреймворке проходит легче.
Решенные технические проблемы
При разработке фронтенда команда столкнулась со следующими сложностями: изначально не было ясно, какие именно модули стоит разрабатывать таким образом, чтобы их можно переиспользовать.
Например, модуль модального окна на первом этапе разработки был частью страницы таблицы треков. Но, в процессе разработки страницы загрузки трека оказалось, что на ней, для взаимодействия с пользователем, так же нужны модальные окна. Поэтому пришлось перенести модальное окно в отдельный класс, которому передаются в качестве аргументов следующие данные: сообщение и содержание кнопок при успешном завершении операции, сообщение и содержание кнопок при завершении операции с ошибкой. Такое модальное окно можно использовать повторно в любой части приложения.
Также, выяснилось, что для Leaflet нет готового решения для показа треков, которое бы устраивало нас (есть плагины, но они перегружены лишними функциями и, к тому же, часто работают не так, как ожидалось). Пришлось написать собственный метод для работы с отображением треков.
Разработка бекенда также сопутствовалась решением различных интересных проблем. Главное было понять, как увязать между собой REST, аутентификацию и работу с БД. Отличным примером послужила следующая статья. Архитектура бекенда была взята из неё. Проект был разделён на модули, отвечающие каждый за своё — модели для работы с БД, контроллеры для взаимодействия REST-запросов с моделями, роутинг, валидаторы для входящих запросов, а так же middleware (в том, числе, авторизация).
Но самой захватывающей частью разработки бекенда, была работа с файлами GPX, их парсинг и анализ.
Когда файл загружается пользователем, он преобразуется в JSON-объект, из которого удаляется ненужная в рамках нашего проекта информация (при этом, вес файла снижается примерно на 3/4), одновременно высчитывается дистанция (об этом чуть ниже), некоторые поля заполняются (например, имя трека становится таким, как его назвал пользователь при загрузке). После этого JSON-объект преобразуется обратно в файл GPX и сохраняется на диске сервера.
Интересным методом в парсере является метод для подсчёта расстояния исходя из данных трека. Дело в том, что расстояние на земном шаре считается методами ортодромии, а это значит, существует специальная формула. Отличное объяснение с примером расчёта находится тут.
Помимо этого, возникали вопросы организационного характера, например, как разместить проект на сервере Apache+Passenger, после её решения я написал заметку, чтобы не забыть.
Ещё одной проблемой стало то, что при загрузке файла и отправке запроса с хедером Content-Type: Multipart/Form-data, бекенд не принимал его. Оказалось, что в строку хедера необходимо включить Boundary — специальный разделитель для данных. Fetch это делает автоматически, если ему не указывать значение хедера прямо. Потратил много времени на понимание этого, поэтому, для закрепления этого в памяти также написал заметку.
Итоги разработки
Подводя предварительные итоги разработки приложения (предварительные — потому что этот проект не закончит свое развитие просле кроссчека, мы планируем продолжать работу над ним и после окончания обучения), вклады участников проекта соответствуют запланированным: Николай разработал серверную часть, и модуль отображения трека на карте, Анастасия разработала оставшуюся часть фронтенда, а кроме того, самостоятельно нарисовала баннер для фона и иконки для приложения, и разработала дизайн.
В ближайшем будущем мы планируем реализовать создание новых треков, редактирование загруженных, а также создать страницу пользователя, добавить возможности просмотра треков других пользователей и сохранения чужих треков в закладки.
Видео с описанием работы сайта и демонстрацией фич
Приложение и ссылки
- Деплой: gpxies.ru
- Видео с описанием работы сайта
- Скриншот коммитов репозитория фронтенда
- Скриншот коммитов репозитория бекенда
- Ссылки на репозитории rsclone (фронтенд) и gpxies_backend (бекенд)