После 4 лет ожидания у нас был еще один чемпионат мира, полный сюрпризов, и я снова решил сделать футбольный пул, или quiniela, как его называют в Латинской Америке, чтобы обмануть всех моих друзей… Я хочу узнать больше. Мой первый опыт был в 2014 году, когда я использовал PHP и Yii для его создания, но на этот раз я хотел узнать что-то новое и свежее.

Я хочу поделиться своим опытом работы с Node и решением, которого я достиг.

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

Почему именно Node?

Я использую Python для веб-разработки в течение последних лет, и каждый раз, когда я ищу новости, все они говорят о Node, поэтому я решил присоединиться к крутому детскому клубу и попробовать его.

Правила

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

  • Все пользователи должны ввести прогноз матча перед его стартом.
  • Если прогноз счета является точным совпадением с окончательным результатом, он получает 3 очка.
  • Если совпадение не является точным, но есть тот же победитель, он получает 1 очко. Пример: если пользователь А идет со счетом 3–0, а фактический счет 2–1, то пользователь получает 1 одно очко.
  • Если матч закончился вничью, и пользователь также предсказывает ничью, он получит 1 очко. Пример: если пользователь B идет 3–3 и его оценка 1–1, то пользователь получает 1 балл.
  • Побеждает пользователь, набравший наибольшее количество очков.

Структура

(Полный код можно получить здесь)

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

api/
|-- config.js
|-- controllers
|   |-- database.js
|   `-- positions.js
|-- matches
|   |-- index.js
|   `-- matches.js
|-- teams
|   |-- index.js
|   `-- teams.js
`-- users
    |-- index.js
    `-- users.js

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

Конфигурационный файл содержит переменные, используемые для изменения поведения приложения, и другую конфигурацию, такую ​​как, например, идентификатор для Oauth.

Краткое описание каждого компонента в каталоге api:

Команды

Для отображения информации обо всех командах или только об одной команде по идентификатору.

Пользователи

Подсчитайте общее количество очков каждого пользователя и обновите прогноз каждого пользователя перед матчем.

Спички

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

Контроллеры

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

База данных

Вторая моя проблема заключалась в том, чтобы найти способ хранить информацию о командах, прогнозах, датах и ​​результатах. Хотя большинство руководств, которые я нашел, рекомендовали другой подход (например, нереляционные базы данных), я решил использовать Postgres в основном потому, что это то, что я обычно делаю, и не хотел добавлять больше сложности, так как у меня был жесткий крайний срок с первым совпадением. начиная с пары дней (промедление, ура!).

База данных проста и содержит всего четыре таблицы:

  • Матчи: хранит дату и окончательные результаты каждого матча.
  • Команды: название каждой команды.
  • Прогнозы: оценка, которую прогнозирует каждый пользователь.
  • Пользователи: имя, используемое для идентификации каждого пользователя, и адрес электронной почты для входа в систему.

API

Маршрутизация

Для создания API я использовал Экспресс и его мощный компонент роутер. С его помощью я могу разделить маршруты так же, как я создал структуру, и использовать маршрутизатор для создания конечной точки в каждом модуле:

// An example of matches.js inside api/matches
// obtain router
const express = require('express'),
      router = express.Router()
...
// example of an endpoint. 
router.get("/all", (req, res) => {
  console.log("obtain all matches");
  // do stuff
})

А в файле server.js импортирую все маршруты из других модулей:

// require express and import the routes in the api directory
const express = require('express');
      matches = require('./api/matches'),
      teams = require('./api/teams'),
      users = require('./api/users'),
...
// register the routes in the app
app.use('/teams',teams)
.use('/matches', matches)
.use('/users', users)
... // other routes

Postgres

Для управления сеансом базы данных и запросами я использовал Node-postgres. С помощью этой библиотеки вы можете получить URL-адрес базы данных из среды (более безопасный и используемый в некоторых местах, таких как Heroku):

const { DATABASE_URL } = process.env;
var pool = new Pool({
    connectionString: DATABASE_URL
});

Или создайте объект и передайте его пулу:

var pool = new Pool({
      user: 'username',
      host: 'localhost',
      database: 'database_name',
      password: 'my_password',
      port: 5432
    });

Установив соединения, вы можете выполнять такие запросы:

// connect pool and query all teams in table
pool.connect()
  .then(client => {
      return client.query("SELECT * FROM teams")
        .then(data =>{
          // do stuff with the data
          ...
        })

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

Кстати, если вы считаете код запроса некрасивым ... вы правы! Я спускался к черту… ад обратного звонка

Если вы хотите протестировать приложение, выполните следующие действия.

Требования

  • node js (очевидно)
  • npm
  • Postgres
  • браузер или завиток для просмотра ответов

Установка

Сначала клонируйте проект из github:

git clone https://github.com/agmezr/quiniela.git

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

  • api /: контроллеры, представления и ответы
  • assets /: содержит скрипт для базы данных
  • server.js: файл, который настраивает и запускает сервер
  • пакеты json: используются для установки необходимых зависимостей

Установите зависимости проекта с помощью npm:

npm install

Запустите сценарий в assets / database.sql, чтобы создать базу данных:

psql <db name | postgres> -f assets/database.sql

После установки зависимостей и db запустите сервер, используя:

node server.js

Если все в порядке, вы должны увидеть такое сообщение:

Staring app on 8080

Теперь откройте свой браузер (или используйте curl) и войдите в localhost: 8080 / index, чтобы увидеть потрясающий ответ:

{"status":"ok"} 

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

http://localhost:8080/teams/1

вы увидите такой ответ:

[{"id":1,"name":"Russia","grp":"A"}]

Следующие шаги

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

Вывод

Когда один из моих кулаков подошел к Node, я хочу сказать, что работать с ним было очень приятно. Есть много руководств, помогающих новичкам, включая официальную документацию и множество других библиотек, которые помогут вам с общими задачами, такими как безопасность, подключение к базе данных и т. Д. Конечно, есть некоторые вещи, которые сначала трудно понять, например Promises и новые Синтаксис ES6, но ничего, что нельзя исправить за несколько часов написания кода.

Мой совет, если вы хотите попробовать Node JS, - создайте что-нибудь легкое и увлекательное, как я, и остерегайтесь ада обратных вызовов!