Рубрики
Без рубрики

Застеживать и PostgreSQL RESP API

Введите «Speed Force» из документации, застегивайте быструю и низкую накладную веб … Помечено Postgres, Node, JavaScript, WebDev.

Введите «Сила скорости»

От Документация Castify – это быстрый и низкий накладной веб-каркас для Node.js.

Итак, я решил исследовать некоторые потрясающие функции, которые скрывают предложения, включая, но не ограничиваясь ограничениями, скоростью, расширяемостью через плагины и декораторы, проверка схемы и сериализацию и регистрацию. Я погрузился в их Документация , который отлично, кстати, с помощью некоторых репозиториев GitHub и решил построить некоторые конечные точки API для отдыха, работающие на Castify и PostgreSQL базы данных.

Вы можете проверить Исходный код или следовать в этом посте.

Начиная

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

Перейдите к корневой папке вашего проекта и запустите NPM init Чтобы инициализировать ваш проект. Создать SRC Папка для исходного кода вашего проекта и создать index.js файл в качестве точки входа.

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

Установка Nodemon.

Номемон Это зависимость Dev, которая отслеживает ваши изменения файла и автоматически перезапускает свой сервер.

Вы можете установить Nodemon локально с NPM:

npm install nodemon --save-dev

Добавьте этот сценарий NPM в скрипты в package.json файл

"start": "nodemon src/index.js"

Установка застегивания

Установить с NPM:

npm i fastify --save

Привет мир: Запуск и запуск вашего сервера

В index.js Файл Добавить этот блок кода:

const fastify = require('fastify')({logger: true}) 
fastify.get('/', async (request, reply) => { 
     reply.send({ hello: 'world' }) 
  }) 
async function start()  { 
    try{ 
        await fastify.listen(3000) 
    } catch(err) { 
        fastify.log.error(err) 
        process.exit(1) 
    } 
} 
start()

В первой строке мы создаем экземпляр Sastifify и включить журнал, скрывать использование Pino. как его регистратор. Затем мы определяем Получить Метод маршрута, укажите конечную точку домашней страницы '/' и пройти в функцию обработчика маршрута, которая отвечает объектом {Здравствуйте: «Мир»} Когда мы делаем запрос на получение домашней страницы.

Мы создали наш экземпляр Server Server (завернутый в нашу start Функция) и прослушать запросы на порт 3000. Чтобы запустить сервер, запустите NPM начать На вашем терминале в корневой папке. Теперь вы должны быть запущены, и в терминале будет зарегистрировано следующее:

{"level":30,"time":1618477680757,"pid":5800,"hostname":"x","msg":"Server listening at http://127.0.0.1:3000"}

Когда вы посещаете домашнюю страницу, вы должны увидеть ответ:

curl http://localhost:3000/ 
{"hello":"world"}

Отлично у нас есть наш сервер!

Плагины

Мы можем продлить функциональность Castify с плагинами. Из документации:

Плагин может быть набором маршрутов, декоратор сервера или что-то еще.

Мы можем ревертировать наш маршрут в плагин и поставить его в отдельный файл i.e Marross.js Затем потребуйте в нашем корневом файле и используйте Регистрация API добавить маршрут или другие плагины.

Создать Marross.js Файл и добавьте этот код:

async function routes(fastify, options) { 
    fastify.get('/', async (request, reply) => { 
        reply.send({ hello: 'world' }) 
    }) 
} 
module.exports= routes

Затем мы требуем нашего модуля в index.js и зарегистрируйте это.

const fastify = require('fastify')({logger: true})
const route  = require('./routes')
fastify.register(route)
async function start()  {
   ...
}
start()

Запрос на домашнюю страницу все равно должен работать. Отлично, у нас есть первый плагин.

Создание нашей базы данных

Для создания базы данных нам сначала нужно подключиться к PSQL Интерактивный терминал для работы с Postgres.

Для подключения к PSQL Запустите команду в терминале:

psql -h localhost -U postgres

Введите свой пароль в приглашении для подключения к PSQL Отказ

Создать база данных базы данных Заявление создает базу данных:

CREATE DATABASE todos;

Для подключения к созданной базе данных Запустите команду:

\c todos

Чтобы создать наш стол, запустите утверждение

CREATE TABLE todos ( 
    id UUID PRIMARY KEY, 
    name VARCHAR(255) NOT NULL, 
    "createdAt" TIMESTAMP NOT NULL, 
    important BOOLEAN NOT NULL, 
    "dueDate" TIMESTAMP, 
    done BOOLEAN NOT NULL 
);

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

Для интерфейса с базой данных PostgreSQL нам нужна Узел-postgres или PG Водитель.

Чтобы установить Узел-postgres :

npm install pg

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

Давайте создадим плагин для подключения к нашей базе данных. Создать db.js Файл и добавьте следующий код:

const fastifyPlugin = require('fastify-plugin') 
const { Client } = require('pg') 
require('dotenv').config() 
const client = new Client({ 
    user: 'postgres', 
    password:process.env.PASSWORD, 
    host: 'localhost', 
    port: 5432, 
    database: process.env.DATABASE 
}) 
async function dbconnector(fastify, options) { 
    try { 
        await client.connect() 
        console.log("db connected succesfully") 
        fastify.decorate('db', {client}) 
    } catch(err) { 
        console.error(err) 
    } 
} 
module.exports= fastifyPlugin(dbconnector)

Давайте пропустим Застегитьplugin часть первой.

Мы требуем Клиент Модуль из Узел-postgres и создать клиент Экземпляр, проходящий в объекте с различными полями.

Обязательно создать .env Файл и добавить:

PASSWORD='yourpassword'

Установите и требуют Доценв Модуль для загрузки переменных среды

npm i dotenv

Затем мы создаем наши dbconnector Плагин и внутри блока попробуйте, мы подключаемся к нашей базе данных Postgres.

Внутри блока вы также можете увидеть:

fastify.decorate('db', {client})

Что такое функция украшения?

Пристеживать, чтобы добавить функциональность в экземпляр застегивания, вы используете декораторы . Мы используем Украсить API, пропустите имя недвижимости «БД» Как первый аргумент и ценность нашего клиент экземпляр ( {Client} ) как второй аргумент. Значение также может быть функцией или строкой. Мы экспортируем плагин, завернутый в Застегитьplugin модуль.

Требуется модуль в index.js Файл и зарегистрируйте его.

const dbconnector = require('./db')
fastify.register(dbconnector)
fastify.register(route)
async function start()  {
  ...
}
start()

Теперь мы можем получить доступ к нашему экземпляру клиента в других частях приложения, например, в наших маршрутах, чтобы запросить данные, используя castify.db.client Отказ

Давайте сделаем шаг назад к Застегитьplugin модуль. Зачем обернуть наш плагин с застегиванием? Когда мы регистрируем плагин, мы создаем контекст Castify (инкапсуляцию), что означает доступ к данным вне нашего зарегистрированного плагина, ограничен. В этом случае мы не можем получить доступ к нашей базе данных клиент экземпляр с использованием castify.db.client где угодно в нашем приложении.

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

Сериализация

Давайте ревертировать нашу домашнюю страницу, чтобы вернуть информацию из нашей базы данных:

async function routes(fastify, options) {  
    //Access our client instance value from our decorator
    const client = fastify.db.client
    fastify.get('/', {schema: allTodos}, async function (request, reply) { 
            try { 
                const {rows} = await client.query('SELECT * FROM todos') 
                console.log(rows) 
                reply.send(rows) 
            } catch(err) { 
                throw new Error(err) 
            } 
        })
}  
module.exports= routes

Мы сначала доступ к нашей базе данных клиент экземпляр и назначить его клиент Переменная. Внутри наших маршрутов мы запрашиваем все столбцы из нашей базы данных, используя Shothand * и отправьте возвращенные TODOS, используя Reply.send (строки) – Вы также можете использовать возвратные ряды . Убедитесь, что вы добавляете некоторые TODOS в вашей базе данных в первую очередь в PSQL Терминал I.E:

INSERT INTO todos (id, name, "createdAt", important, "dueDate",  done) 
VALUES ('54e694ce-6003-46e6-9cfd-b1cf0fe9d332', 'learn fastify', '2021-04-20T12:39:25Z', true, '2021-04-22T15:22:20Z', false); 
INSERT INTO todos (id, name, "createdAt", important, "dueDate",  done)  
VALUES ('d595655e-9691-4d1a-9a6b-9fbba046ae36', 'learn REST APIs', '2021-04-18T07:24:07Z',true, null, false);

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

Когда вы смотрите ближе в нашем методе маршрута Get, вы можете увидеть иметь объект нашего второго аргумента с Схема ключ и Alltodos как значение.

Застегивание использует Fast-Json-Stringify Для сериализации вашего ответа тело, когда в параметрах маршрута предусмотрена схема.

Чтобы добавить схему Создать Schemas.js Файл и добавьте Alltodos Schema :

const allTodos = {
    response: {
        200: {
            type: 'array',
            items: {
                type: 'object',
                required: ['id', 'name', 'createdAt', 'important', 'dueDate', 'done'],
                properties: {
                    id: {type: 'string',  format: 'uuid'},                                                              
                    name: {type: 'string'},                                           
                    createdAt:{type: 'string',format: "date-time"},                  
                    important: {type: 'boolean'},
                    dueDate: {type: 'string',format: "date-time"},
                    done: {type: 'boolean'},
                }
            }
        }
    }
}

Castify рекомендует использовать JSON SCHEMA Для сериализации ваших результатов вы можете прочитать, как написать JSON Schema здесь Отказ

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

Не забудьте требовать модуля в Marross.js файл.

Проверка

В Marross.js Файл, давайте добавим Пост Маркт метода внутри нашего плагина маршрута, чтобы добавить TODOS в нашу базу данных.

fastify.post('/', {schema: addTodo}, async function(request, reply) {
            const {name, important, dueDate} = request.body
            const id = uuidv4()
            const done = false
            createdAt = new Date().toISOString()
            const query = {
                    text: `INSERT INTO todos (id, name, "createdAt", important, "dueDate", done)
                                    VALUES($1, $2, $3, $4, $5, $6 ) RETURNING *`,
                    values: [id, name, createdAt, important, dueDate, done],
                    }
            try {
                    const {rows} = await client.query(query)
                    console.log(rows[0])
                    reply.code(201)
                    return {created: true}
            } catch (err) {
                    throw new Error(err)
            }

    })

Мы позволяем клиенту отправить объект JSON в организме Имя Toddo, важно и Duedate характеристики.

Затем мы генерируем уникальный ID , назначить ложь сделано и отметка TOMESTAMP, назначенного Создать Отказ

Для создания уникального ID установки uuid :

npm install uuid

Требуется модуль в Marross.js :

const { v4: uuidv4 } = require('uuid');

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

После успешной вставки мы отправляем 201 создан код состояния обратно к клиенту. В Schemas.js Файл, давайте добавим схему проверки для наших TODOS:

const addTodo = {
    body: {
        type: 'object',
        required: ['name'],
        properties: {
            name: {type: 'string',},
            dueDate: {type: 'string', format: 'date-time', nullable: true, default: null},
            important: {type: 'boolean', default: false},
        }
    },
    response: {
        201: {
            type: 'object',
            properties: {
                created: {type: 'boolean'}
            }
        }
    }

}

Застегивание использует AJV для проверки запросов. Мы ожидаем, что клиент всегда отправит Имя TODO, добавив его в нужный массив недвижимости.

Duedate Собственность может быть опущена клиентом, посредством которого это будет null по умолчанию. Это сделано возможным, установив Nullable недвижимость в правда который позволяет экземпляру данных быть JSON NULL. Когда при условии, что он должен быть в формате «Дата время».

клиент Может при желании указать, важно ли TODO или он возвращается к по умолчанию.

Если вышеуказанные условия не удовлетворены, Castify автоматически отправит объект ошибок с сообщением об ошибке.

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

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "body should have required property 'name'"
}

Здорово! Наша проверка работает

Добавление других конечных точек отдыха

Обновление Todo Давайте позвольте пользователям устанавливать их так же, как и важность TODO или изменений Duedate. Для этого давайте добавим Патч Маркет метода на наши маршруты плагин.

fastify.patch('/:id',{schema: updateTodo}, async function (request, reply) {
        const id = request.params.id
        const {important, dueDate, done} = request.body
        const query = {
                text:  `UPDATE todos SET 
                                important = COALESCE($1, important), 
                                "dueDate" = COALESCE($2, "dueDate"), 
                                done = COALESCE($3, done) 
                                WHERE id = $4 RETURNING *`,
                values : [important, dueDate, done, id]
        }
        try {
                const {rows} = await client.query(query)
                console.log(rows[0])
                reply.code(204)
        } catch (err) {
                throw new Error(err)
        }
})

Мы извлекаем ID Из TODO мы хотим обновить от параметра и значений из тела запроса.

Затем мы создаем наше оператор запроса, обновляя столбцы, предоставленные необязательно, используя Coalesce функция. То есть, если клиенты опускают некоторые свойства в корпусе JSON, мы обновляем только предоставляемые свойства и оставьте остальное, поскольку они находятся в строке Todo.

Затем мы отвечаем на 204 Нет контента Отказ

Давайте добавим схему проверки на наш маршрут:

const updateTodo = {
    body: {
        type: 'object',
        properties: {
            dueDate: {type: 'string', format: 'date-time'},
            important: {type: 'boolean'},
            done: {type: 'boolean'}
        }
    },
    params: {
        type: 'object',
        properties: {
          id: { type: 'string', format: 'uuid' }
        }
    }
}

Пармы проверяют объект параметров.

Удалить Todo.

Чтобы удалить Todo, нам просто нужно ID отправлено в URL-параметр. Добавить Удалить Метод маршрута:

fastify.delete('/:id', {schema: deleteTodo}, async function(request, reply) {
            console.log(request.params)
            try {
                    const {rows} = await client.query('DELETE FROM todos
                    WHERE id = $1 RETURNING *', [request.params.id])
                    console.log(rows[0])
                    reply.code(204)
            } catch(err) {
                    throw new Error(err)
            }
    })

Давайте добавим схему проверки для нашего Удалить маршрут:

const deleteTodo = {
    params: {
        type: 'object',
        properties: {
            id: {type: 'string', format: 'uuid'}
        }
    }
}

Заключение:

Дайте застегивать попытку и «возьми свой HTTP-сервер до нестируемой скорости» ~ Маттео Коллина Отказ

Вы можете проверить исходный код проекта здесь

Использованная литература:

Застегивайте примеры; REPOS GitHUB:

Оригинал: “https://dev.to/kenwanjohi/fastify-and-postgresql-rest-api-2f9l”