Инструкция по созданию серверного приложения на nodejs + express

До того, как начать

Предполагается, что Вы уже знакомы с JavaScript. Если нет, то необходимо что-то сделать с этим. Например почитать онлайн учебник: https://learn.javascript.ru/

Node.js что это?

Node.js — это кроссплатформенная среда исполнения JavaScript с открытым исходным кодом, основанная на движке V8 компании Google и предназначенная для создания web-приложений на стороне сервера.

Установка

Для загрузки нужно перейти на официальный сайт https://nodejs.org/en/. На главной странице мы сразу увидим две возможные опции для загрузки: самая последняя версия NodeJS и LTS-версия.

Cкачиваем, устанавливаем. Там же можно найти инструкцию по утановке:

centos:

1
2
3
curl —silent —location https://rpm.nodesource.com/setup_9.x | sudo bash - 
sudo yum -y install nodejs
sudo yum install gcc-c++ make

ubuntu:

1
2
3
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash - 
sudo apt-get install -y nodejs
sudo apt-get install -y build-essential

Проверить правильность установки можно командой:

1
node --version

Команда покажет текущую версию программы.

REPL

После установки NodeJS нам становится доступным такой инструмент как REPL.
REPL (Read Event Printed Loop) представляет возможность запуска выражений на языке JavaScript в командной строке или терминале.

Так, запустим командную строку (на Windows) или терминал (на OS X или Linux) и введем команду node. После ввода этой команды мы можем выполнять различные выражения на JavaScript.

Пакеты в Node.js

Вкратце, пакетом в Node.js называется один или несколько JavaScript-файлов, представляющих собой какую-то библиотеку или инструмент.

npm (аббр. node package manager) — это стандартный менеджер пакетов, автоматически устанавливающийся вместе с Node.js. Он используется для скачивания пакетов из облачного сервера npm, либо для загрузки пакетов на эти сервера.

Перед стартом проекта

Создайте директорию проекта, где будет храниться весь код. Затем откройте терминал, выполните команду для инициализации:

1
npm init

После ответа на вопросы в директории проекта появится файл ‘package.json’

Express

Express - это минималистичный и гибкий веб-фреймворк для приложений Node.js, построенный на базе фреймворка connect.

Основное предназначение Express - маршрутизация и промежуточная обработка с минимальной собственной функциональностью: приложение Express, по сути, представляет собой серию вызовов функций промежуточной обработки (middleware).

Для утановки Express в терминале из директории проекта запустите команду:

1
npm install express

Как это применить

Создаем файл server.js.

Для использования фреймворка Express, необходимо подключить модуль express, и создать приложение.

1
2
var express = require('express'); 
var app = express();

Запустить приложение можно командой:

1
2
3
app.listen(8080, function(){
console.log('server start on port 8080');
})

В результате сервер запустится, но если в браузере выполнить запрос к приложению localhost:8080, то получим ошибку:

Cannot GET /

Это происходит потому, что в программе нет ни одного маршрута.

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

Маршрутизация определяет, как приложение отвечает на клиентский запрос к конкретному адресу, и определенному методу HTTP запроса.

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

Для определения маршрута используют следующую структуру:

1
app.METHOD(path, handler)

app – экземпляр express приложения
METHOD – метод HTTP запроса
path – путь на сервере
handler – функция обработчик на указанный путь

Продолжаем применять

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var express = require('express');
var app = express();

// Вызываем метод get, он установит обработчик, который будет срабатывать на get запросы, для маршрута '/'
app.get('/', function(request, response){
console.log(request.url);
response.send('<h1>Hello, world!</h1>');
});

// То же самое для маршрута '/about'
app.get('/about', function(request, response){
console.log(request.url);
response.send('<h1>About Page</h1>');
});
app.listen(8080);

Что еще?

Middleware-function

Функции промежуточной обработки (middleware) - это функции, имеющие доступ к объекту запроса req, объекту ответа res и к следующей функции промежуточной обработки в цикле “запрос-ответ” приложения next.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var express = require('express');
var app = express();

// для регистрации middleware используется функция use, all, app.METHOD()
// 1. request - данные запроса
// 2. response - объект для управления ответом
// 3. next - следующая в конвейере обработки функция

app.use('/', function(request, response, next){
console.log('Prehandler...');
// передаем управление следующему обработчику
next();
});

app.get('/', function(request, response){
console.log('Main handler');
// завершаем ответ от сервера
response.end();
});

app.listen(8080);

Таким образом, выполнятся обе функции при обращении по корневому маршруту.

Routing

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var express = require('express');
var app = express();

var router = express.Router();

router.route("/")
.get(function(req, res){
res.send("List of products. Get method.");
})
.post(function(req, res){
res.send("Product created. POST method.");
});
router.route("/:id")
.get(function(req, res){

res.send(`Product ${req.params.id}`);
});

app.use("/products", router);

app.get("/", function(req, res){
res.send("Главная страница");
});

app.listen(8080);

При выполении запроса localhost:8080/products маршрут будет определяться из router. Выполнится соответствующая функция-обработчик.

Финиш

В инструкции вы познакомились с node.js+express. Этого будет достаточно для быстрого старта.
Для получения большей информации листайте источники.

Источники:

node:
https://nodejs.org/en/
https://itvdn.com/ru/video/node_js/express - платный ресурс к сожалению, но полезный.
https://learn.javascript.ru/screencast/nodejs - альтернатива

npm:
https://www.npmjs.com/

express:
http://expressjs.com/ru/
https://nodeguide.ru/doc/modules-you-should-know/express/
http://expressjs.com/ru/4x/api.html - api справочник express

Инструкция по созданию серверного приложения на nodejs + koa

Koa - микрофреймфорк, разработанный командой разработчиков фреймворка Express, и призванный использовать самые последние стандарты языка JavaScript.
Koa “предлагает” активно использовать самые последние стандарты в языке, включая синтаксис async/await, который позволяет избавиться от ужасно нечитаемого “callback hell” и является хорошей альтернативой построения цепочек Promise. Углубляться в синтаксис здесь не будем, это не тема статьи.
Сам Koa, являясь микрофреймворком, из коробки содержит только middleware систему, в нем даже нет маршрутизации. Все это можно получить, подключив необходимую функциональность в middleware chain.

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

Требования

Koa требует версию Node не меньше 7.6.0.
Использовать более старые версии можно, если подключить Babel, но тогда немного теряется посыл самого Koa (см. выше).
Т.к. мы собираемся использовать достаточно новые фичи языка, то лучше не скупиться, и ставить последнюю стабильную версию Node.

Подготовка среды

Про Node.js

Если Node не установлен, то вам необходимо сюда. Если же у вас еще и Linux или macOS, можно установить через менеджер пакетов - здесь сказано, как.
Чтобы проверить, что с Node все в порядке, можно набрать команду:

1
$ node --version

Она выведет текущую версию Node.
Также и про NPM (Node Package Manager) не забудем:

1
$ npm --version

Если хочется NVM (Node Version Manager), то вы наверняка знаете, что это такое, и проблем поставить нужную версию Node.js у вас не составит.

Установка зависимостей

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

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

1
$ npm init

NPM задаст несколько вопросов. Отвечаем хотя бы на имя пакета и имя автора.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (ex) koa-simple-app
version: (1.0.0)
description: Koa simple application
entry point: (index.js)
test command:
git repository:
keywords:
author: Nariman Safiulin <woofilee@gmail.com>
license: (ISC)
About to write to <..>\package.json:

{
"name": "koa-simple-app",
"version": "1.0.0",
"description": "Koa simple application",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Nariman Safiulin <woofilee@gmail.com>",
"license": "ISC"
}


Is this ok? (yes)

У нас должен был появиться файл package.json.

Поставим koa:

1
$ npm i koa

Hello, World!

Создадим файл index.js, и заполним его слегка измененным стандартным примером Koa.

1
2
3
4
5
6
7
8
9
10
11
const Koa = require('koa');

const app = new Koa();

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Код достаточно простой.
Мы создаем объект приложения. С помощью метода use мы цепляем новый middleware в цепочку. Все middleware будут выполняться по очереди с каждым запросом. В каждый middleware передаются два аргумента - ctx и next, где ctx - это, очевидно, контекст запроса, а next - следующая middleware в цепочке. В последнем middleware в цепочке next можно и не принимать (как в примере).
После чего мы говорим Koa слушать порт 3000. Небольшой callback позволяет нам понять, что сервер действительно запустился, а не завис.

Теперь можно запустить сервер:

1
$ node index.js

Если сервер успешно запустился, то можно зайти в браузер, и в адресной строке перейти по адресу localhost:3000. Должно отобразиться привычное всем Hello, World!.

Подронее про цепочки middleware, структуру контекста и события можно прочитать на сайте Koa.

С чем использовать

Альтернативы есть почти к каждому и ниже перечисленного. Их можно поискать в ссылках внизу статьи.

Koa-router

Библиотека позволяет получить необходимую функциональность роутинга запросов на разные обработчики. Без этого навеса навряд ли можно сделать что-то более менее серьезнее Hello, World!.
Кроме koa-router есть еще куча других аналогов, например более простой koa-route, которому сложно придумать какое-либо применение для грандиозных целей, и роутер с валидацией входящих и исходящих данных joi-router. Тем не менее, koa-router самый популярный на данный момент среди роутеров, и имеет сбалансированную функциональность, ничего лишнего.

1
$ npm i koa-router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Koa = require('koa');
const Router = require('koa-router'); // Изменения здесь

const app = new Koa();
const router = new Router(); // Инициализируем роутер

router.get('/', (ctx, next) => { // И здесь, мы явно принимаем GET запрос
ctx.body = 'Hello, World!';
});

app.use(router.routes()).use(router.allowedMethods()); // Здесь мы добавляем роуты в цепочку, а также разрешаем вводим OPTIONS запросы.

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Подробнее про koa-router можно почитать здесь.

Koa-bodyparser

Koa из коробки, как мы уже выяснили, мало что умеет. Парсить сложные запросы тоже.
Если нам нужно принимать запросы с JSON телом, то этот навес необходим.

1
$ npm i koa-bodyparser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const Koa = require('koa');
const BodyParser = require('koa-bodyparser'); // Изменения здесь

const app = new Koa();

app.use(bodyParser()); // Подключить парсер нужно до наших роутов

app.use(async ctx => {
// Распарсенный запрос будет лежать в ctx.request.body
// Если парсить нечего, будет пустой объект
ctx.body = ctx.request.body;
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Подробнее про koa-bodyparser можно почитать здесь.

Koa-logger

Логи того, что приходит, и что уходит, тоже нужны. Для разработки пойдет вариант koa-logger.
Выглядеть будет примерно так (взято из странички самого пакета):

1
2
3
4
5
6
7
8
<-- GET /
--> GET / 200 835ms 746b
<-- GET /
--> GET / 200 960ms 1.9kb
<-- GET /users
--> GET /users 200 357ms 922b
<-- GET /users?page=2
--> GET /users?page=2 200 466ms 4.66kb

Не густо. Если хочется совсем много информации, то можно попробовать bunyan-logger.

1
$ npm i koa-logger
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Koa = require('koa');
const Logger = require('koa-logger'); // Изменения здесь

const app = new Koa();

app.use(Logger()); // Опять же, логгер раньше наших роутов

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Репозиторий koa-logger здесь.

@koa/cors

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

1
$ npm i @koa/cors@2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Koa = require('koa');
const CORS = require('@koa/cors'); // Изменения здесь

const app = new Koa();

app.use(CORS()); // Раньше роутов!

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Репозиторий @koa/cors здесь.

Koa-compress

Сжатие ответов от сервера.

1
$ npm i koa-compress
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const Koa = require('koa');
const Compress = require('koa-compress'); // Изменения здесь

const app = new Koa();

app.use(Compress({
filter: function (content_type) {
return /text/i.test(content_type)
},
threshold: 2048,
flush: require('zlib').Z_SYNC_FLUSH
})); // Раньше роутов! Здесь мы сжимаем любые текстовые ответы.

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Подробнее про koa-compress здесь.

Koa-session

Если необходимы сессии на cookie, то это неплохой вариант.

1
$ npm i koa-session
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const Koa = require('koa');
const Session = require('koa-session'); // Изменения здесь

const app = new Koa();

app.keys = ['secret key']; // По умолчанию, нам требуется какой-то набор байтов, с помощью которого можно подписать cookie сессию

app.use(Session(app)); // И здесь, все опции по умолчанию

app.use(async ctx => {
// Считаем, сколько раз мы вывели Hello, World!.
// Не забываем, что браузер еще запрашивает favicon, поэтому число может увеличиваться на 2.
let n = ctx.session.views || 0;
ctx.session.views = ++n;
ctx.body = `Hello, World! x${n}`;
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Подробнее про опции koa-session здесь.

Koa-JWT

Ну и, конечно, JWT. Очень полезны при разработке API. Быстрый пример к ним не привести, так что можно прочитать README в репозитории пакета.

1
$ npm i koa-jwt

Подробнее про koa-jwt здесь.

Вместо заключения

Koa, по сути, выполняет свою единственную важную функцию - это принимать запросы на сервер, и применять на них цепочку middleware. Это позволяет добиться хорошей гибкости в разработке приложения, и использовать только то, что необходимо.
Он также сильно похож на Express.
Так что проблем с ним возникнуть не должно.

Полезные ссылки

Инструкция по созданию серверного приложения на nodejs + koa + mongodb

Koa

Koa - микрофреймфорк, разработанный командой разработчиков фреймворка Express, и призванный использовать самые последние стандарты языка JavaScript.
Koa “предлагает” активно использовать синтаксис async/await, который позволяет избавиться от ужасно нечитаемого callback hell и является более хорошей альтернативой Promise. Углубляться в синтаксис здесь не будем, это не тема статьи.
Сам Koa, являясь микрофреймворком, из коробки содержит только middleware систему, в нем даже нет маршрутизации. Все это можно получить, подключив необходимую функциональность в middleware chain.

Требования

Koa требует версию Node не меньше 7.6.0.
Использовать более старые версии можно, если подключить Babel, но тогда немного теряется посыл самого Koa (см. выше).
Версия MongoDB нас не интересует, поставим самую последнюю.

Подготовка среды

Про Node.js

Если Node не установлен, то вам необходимо сюда. Если же у вас еще и Linux или macOS, можно установить через менеджер пакетов - здесь сказано, как.
Чтобы проверить, что с Node все в порядке, можно набрать команду:

1
$ node --version

Она выведет текущую версию Node.

Также и про NPM:

1
$ npm --version

Установка зависимостей

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

Инициализируем среду пакета:

1
$ npm init

NPM задаст несколько вопросов. Отвечаем хотя бы на имя пакета и имя автора.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (ex) exampleapp
version: (1.0.0)
description: Example application on Koa and PostgreSQL
entry point: (index.js)
test command:
git repository:
keywords:
author: Nariman Safiulin <woofilee@gmail.com>
license: (ISC)
About to write to <..>\package.json:

{
"name": "exampleapp",
"version": "1.0.0",
"description": "Example application on Koa and PostgreSQL",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Nariman Safiulin <woofilee@gmail.com>",
"license": "ISC"
}


Is this ok? (yes)

У нас должен был появиться файл package.json.

Поставим koa:

1
$ npm i koa

Также поставим что-то для роутинга запросов. Будем использовать koa-router, как самый популярный и полнофункциональный вариант.
И заодно koa-logger, чтобы видеть наши запросы к серверу в терминале.

1
$ npm i koa-router koa-logger

Для общения с базой можно использовать пакет koa-mongo.

1
$ npm i koa-mongo

MongoDB

Про Mongo

MongoDB — документоориентированная система управления базами данных (СУБД) с открытым исходным кодом. MongoDB реализует новый подход к построению баз данных, где нет таблиц, схем, запросов SQL, внешних ключей и многих других вещей, которые присущи объектно-реляционным базам данных.

Установка

Скачать установщик MongoDB можно отсюда. Предоставляются Community и Enterprise версии.
После установки надо создать на жестком диске каталог, в котором будут находиться базы данных MongoDB. В ОС Windows по умолчанию MongoDB хранит базы данных по пути C:\data\db, поэтому, если вы используете Windows, вам надо создать соответствующий каталог. В ОС Linux и MacOS каталогом по умолчанию будет /data/db.
Если же возникла необходимость использовать какой-то другой путь к файлам, то его можно передать при запуске MongoDB во флаге –dbpath.

Запуск сервера MongoDB

После создания каталога для хранения БД можно запустить сервер MongoDB. Сервер представляет приложение mongod, которое находится в папке bin. Для этого запустим командную строку (в Windows) или консоль в Linux и там введем соответствующие команды. Для ОС Windows это будет выглядеть так (предполагается, что MongoDB уствновился в C:\mongodb):

1
2
cd c:\mongodb\bin
mongod

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

1
C:\mongodb\bin\mongod.exe --dbpath d:\test\mongodb\data

В данном случае предполагается, что базы данных у нас будут находиться в каталоге d:\test\mongodb\data.
И после удачного запуска сервера мы сможем производить операции с бд через оболочку mongo. Эта оболочка представляет файл mongo.exe, который располагается в выше рассмотренной папке установки. Запустим этот файл:

1
2
cd c:\mongodb\bin
mongo

Если все установилось верно, и сервер запустился, терминал будет ожидать ввода запросов для взаимодействия с БД.
По умолчанию, MongoDB не использует какие-либо способы авторизации для доступа к базе данных. Сами разработчики MongoDB объясняют это тем, что всю логику должно содержать в себе приложение, а база должна делать то, для чего она лучше всего и предназначена — хранение и управление данными. Поэтому в этой статье соединение с авторизацией рассмотрено не будет.
База данных будет автоматически создана при первом обращении к ней (на запись).
Выйти можно, набрав exit.

Hello, World!

Создадим файл app.js, и заполним его немного измененным стандартным примером Koa. Из кода все достаточно понятно.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
'use strict'
const Koa = require('koa');
const Router = require('koa-router');
const Logger = require('koa-logger');

const app = new Koa();
const router = new Router();

// Отвечаем миру на GET запросы
router.get('/', async (ctx) => {
ctx.body = 'Hello, World!\n';
});

// Отвечаем на имя на GET запросы. :name здесь - это часть URL, и является аргументом
router.get('/:name', async (ctx) => {
ctx.body = `Hello, ${ctx.params.name}!\n`;
});

// Логгер
app.use(Logger());
// Добавим все роуты. Второй middleware отвечает на OPTIONS запросы.
app.use(router.routes()).use(router.allowedMethods());

// Слушаем порт, запускаем сервер
app.listen(3000, () => {
console.log('Server running on port 3000');
});

Теперь можно запустить сервер:

1
$ node app.js

Если сервер успешно запустился, то можно зайти в браузер, и в адресной строке перейти по адресу http://localhost:3000/. Мы должны увидеть приветствие. Также, если к адресу добавить имя, т.е. н-р http://localhost:3000/Elisey, мы должны увидеть свое имя в ответе.
В терминале мы должны увидеть примерно такую картину:

1
2
3
4
5
6
node app.js
Server running on port 3000
<-- GET /
--> GET / 200 19ms 14b
<-- GET /Elisey
--> GET /Elisey 200 3ms 15b

Теперь свяжемся с базой.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
'use strict';
//Для этого добавим соответствующий модуль
const Mongo = require('koa-mongo');
// Используем Mongo
app.use(Mongo());

//Для пустых GET-запросов
router.get('/', async (ctx) => {
//С помощью метода find ищем необходимый документ в коллекции first_collection
const result = await ctx.mongo.db('test').collection('first_collection').find({ text: "Hello, world!" }).toArray();
//Если его нет, добавляем с помощью метода insert
if (result.length === 0)
ctx.mongo.db('test').collection('first_collection').insert({ text: "Hello, world!" });
var helloWorld = await ctx.mongo.db('test').collection('first_collection').find({ text: "Hello, world!" }).toArray();
ctx.body = helloWorld[0].text;
});

// Также поступим и с "именными" GET-запросами
router.get('/:name', async (ctx) => {
const result = await ctx.mongo.db('test').collection('first_collection').find({ text: ctx.params.name }).toArray();
if (result.length === 0)
ctx.mongo.db('test').collection('first_collection').insert({ text: ctx.params.name });
var name = await ctx.mongo.db('test').collection('first_collection').find({ text: ctx.params.name }).toArray();
name = name[0].text;
ctx.body = `Hello, ${name}!\n`;
});

Можно перезапустить сервер и увидеть результат.

Инструкция по созданию серверного приложения на nodejs + koa + postgresql

Koa - микрофреймфорк, разработанный командой разработчиков фреймворка Express, и призванный использовать самые последние стандарты языка JavaScript.
Koa “предлагает” активно использовать синтаксис async/await, который позволяет избавиться от ужасно нечитаемого “callback hell” и является более лучшей альтернативой Promise. Углубляться в синтаксис здесь не будем, это не тема статьи.
Сам Koa, являясь микрофреймворком, из коробки содержит только middleware систему, в нем даже нет маршрутизации. Все это можно получить, подключив необходимую функциональность в middleware chain.

Требования

Koa требует версию Node не меньше 7.6.0.
Использовать более старые версии можно, если подключить Babel, но тогда немного теряется посыл самого Koa (см. выше).
Версия PostgreSQL нас не интересует, поставим самую последнюю.

Подготовка среды

Про Node.js

Если Node не установлен, то вам необходимо сюда. Если же у вас еще и Linux или macOS, можно установить через менеджер пакетов - здесь сказано, как.
Чтобы проверить, что с Node все в порядке, можно набрать команду:

1
$ node --version

Она выведет текущую версию Node.
Также и про NPM:

1
$ npm --version

Установка зависимостей

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

Инициализируем среду пакета:

1
$ npm init

NPM задаст несколько вопросов. Отвечаем хотя бы на имя пакета и имя автора.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (ex) exampleapp
version: (1.0.0)
description: Example application on Koa and PostgreSQL
entry point: (index.js)
test command:
git repository:
keywords:
author: Nariman Safiulin <woofilee@gmail.com>
license: (ISC)
About to write to <..>\package.json:

{
"name": "exampleapp",
"version": "1.0.0",
"description": "Example application on Koa and PostgreSQL",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Nariman Safiulin <woofilee@gmail.com>",
"license": "ISC"
}


Is this ok? (yes)

У нас должен был появиться файл package.json.

Поставим koa:

1
$ npm i koa

Также поставим что-то для роутинга запросов. Будем использовать koa-router, как самый популярный и полнофункциональный вариант.
И заодно koa-logger, чтобы видеть наши запросы на сервер в терминале.

1
$ npm i koa-router koa-logger

Для общения с базой будем использовать пакет node-postgres. Это не ORM, а обычный драйвер с необходимой функциональностью. Его достаточно для микросервисов.

1
$ npm i pg

PostgreSQL

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

1
$ sudo -u postgres psql

Или на Windows (если не создавали базу вручную, введите свое имя пользователя вместо стандартного postgres):

1
> psql -U postgres

На Linux и macOS, как правило, база уже будет запущена сама.
На Windows же нужно все включить с пинка:

1
2
3
> initdb -U postgres -D data
> pg_ctl -D data start
> psql -U postgres

Здесь postgres - это имя пользователя, лучше его указать по умолчанию, для начала, а data - директория, где будут храниться базы, можно указать любую удобную.
После чего pg_ctl запускает PostgreSQL (с указанием директории с базами).

По окончанию, мы должны увидеть приветственную консоль:

1
postgres=#

Выйти из нее можно, набрав \q.

По умолчанию за нас будет создана база postgres. Нам этого достаточно для целей этого туторила.

Hello, World!

Создадим файл app.js, и заполним его немного измененным стандартным примером Koa. Из кода достаточно все понятно.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const Koa = require('koa');
const Router = require('koa-router');
const Logger = require('koa-logger');

const app = new Koa();
const router = new Router();

// Отвечаем миру на GET запросы
router.get('/', async (ctx) => {
ctx.body = 'Hello, World!\n';
});

// Отвечаем на имя на GET запросы. :name здесь - это часть URL, и является аргументом
router.get('/:name', async (ctx) => {
ctx.body = `Hello, ${ctx.params.name}!\n`;
});

// Логгер
app.use(Logger());
// Добавим все роуты. Второй middleware отвечает на OPTIONS запросы.
app.use(router.routes()).use(router.allowedMethods());

// Слушаем порт, запускаем сервер
app.listen(3000, () => {
console.log('Server running on port 3000');
});

Теперь можно запустить сервер:

1
$ node app.js

Если сервер успешно запустился, то можно зайти в браузер, и в адресной строке перейти по адресу http://localhost:3000/. Мы должны увидеть приветствие. Также, если к адресу добавить имя, т.е. н-р http://localhost:3000/Nariman, мы должны увидеть свое имя в ответе.
В терминале мы должны увидеть примерно такую картину:

1
2
3
4
5
6
7
8
9
10
11
$ node app.js

Server running on port 3000
<-- GET /
--> GET / 200 13ms 14b
<-- GET /favicon.ico
--> GET /favicon.ico 200 7ms 20b
<-- GET /Nariman
--> GET /Nariman 200 10ms 16b
<-- GET /favicon.ico
--> GET /favicon.ico 200 7ms 20b

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

Добавим зависимость:

1
const { Pool } = require('pg');

Перед запуском сервера, добавим код подключения к базе.

1
2
3
4
5
6
7
app.pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'postgres',
password: '', // По умолчанию пароля нет
port: 5432, // Порт по умолчанию
});

Немного изменим наши роуты, чтобы совершить запрос к базе.

1
2
3
4
5
6
7
8
9
router.get('/', async (ctx) => {
const { rows } = await ctx.app.pool.query('SELECT $1::text as message', ['Hello, World!'])
ctx.body = rows[0].message;
});

router.get('/:name', async (ctx) => {
const { rows } = await ctx.app.pool.query('SELECT $1::text as message', [`Hello, ${ctx.params.name}!`])
ctx.body = rows[0].message;
});

Сразу заметим, что Koa умеет преобразовывать результат в JSON, если в качестве ответа вернуть не строку. Если вернуть просто rows, мы увидим JSON ответ.

Можно перезапустить сервер и увидеть результат.

Вместо заключения

Мы написали все в одном файле. Конечно же, уже для реального проекта, нужно составить правильную архитектуру проекта, а также позаботиться о закрытии пула PostgreSQL и соединений к Koa при выключении сервера.

В качестве инструмента для общения с базой можно использовать такие библиотеки, как Sequelize, Bookshelf, Massive, и другие.