Как использовать Redis в качестве базы данных с помощью Node.js и Redis OM


Введение

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

Однако на этом его функциональность не заканчивается, Redis предлагает хорошее количество модулей, которые можно использовать, и один из них — RedisJSON, который предлагает поддержку JSON в Redis, что расширяет его использование в качестве основной базы данных нашего приложения.

И как должно быть понятно из названия и того, что было написано в этом введении, сегодня мы собираемся создать api с простым грубом, но на этот раз мы будем использовать Redis в качестве базы данных.

Начало работы

Для начала давайте создадим новый проект:

mkdir redis-node-crud
cd redis-node-crud
Войти в полноэкранный режим Выйти из полноэкранного режима

Внутри папки создадим окружение node:

npm init -y
Войти в полноэкранный режим Выйти из полноэкранного режима

Далее мы установим необходимые зависимости:

npm install koa @koa/router koa-body redis-om --save
npm install nodemon standard --save-dev
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем мы добавим следующие скрипты в package.json:

{
  "type": "module",
  "scripts": {
    "dev": "nodemon src/main.js",
    "lint": "standard --fix"
  },
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Завершив настройку проекта, мы можем настроить подключение к экземпляру Redis:

// @/src/db.js
import { Client } from 'redis-om'

export const client = new Client()

export const createClient = async () => {
  if (!client.isOpen()) {
    await client.open('redis://localhost:6379')
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Следующим шагом будет создание сущности и схемы нашего api (для упрощения я поместил их в тот же файл, что и конфигурацию базы данных):

// @/src/db.js
import { Client, Entity, Schema } from 'redis-om'

export const client = new Client()

export const createClient = async () => {
  if (!client.isOpen()) {
    await client.open('redis://localhost:6379')
  }
}

class Post extends Entity {}

export const postSchema = new Schema(Post, {
  title: { type: 'string' },
  content: { type: 'string' },
  isPublished: { type: 'boolean' }
})
Войти в полноэкранный режим Выход из полноэкранного режима

После завершения настройки соединения с Redis и определения схемы мы можем начать работу над api роутером, где мы будем выполнять CRUD. И с этим мы можем импортировать необходимые зависимости и модули:

// @/src/routes.js
import Router from '@koa/router'

import { client, postSchema } from './db.js'

const router = new Router()

// ...

export { router }
Вход в полноэкранный режим Выход из полноэкранного режима

Первый маршрут, который мы создадим, будет возвращать все данные, которые мы сохранили в базе данных:

router.get('/posts', async (ctx) => {
  const postRepository = client.fetchRepository(postSchema)
  await postRepository.createIndex()
  const allPosts = await postRepository.search().returnAll()
  ctx.body = allPosts
})
Войти в полноэкранный режим Выход из полноэкранного режима

А поскольку мы не всегда хотим получать все посты, давайте создадим маршрут, который будет возвращать только один пост в соответствии с параметром id, указанным в параметрах запроса:

router.get('/posts/:id', async (ctx) => {
  const postRepository = client.fetchRepository(postSchema)
  const post = await postRepository.fetch(ctx.params.id)
  ctx.body = post
})
Войти в полноэкранный режим Выйти из полноэкранного режима

Помимо возврата данных, нам также необходимо вставить некоторые данные, для этого мы создадим маршрут, в который мы можем добавить свойства, указанные в нашей схеме:

router.post('/post', async (ctx) => {
  const postRepository = client.fetchRepository(postSchema)
  const post = await postRepository.createAndSave({
    ...ctx.request.body
  })
  ctx.body = post
})
Вход в полноэкранный режим Выйти из полноэкранного режима

Если нам нужно обновить одно из свойств конкретного поста, мы создадим маршрут, в параметрах которого будет указан id поста, а в теле запроса — свойства, которые мы хотим обновить:

router.put('/post/:id', async (ctx) => {
  const postRepository = client.fetchRepository(postSchema)
  const post = await postRepository.fetch(ctx.params.id)

  Object.entries(ctx.request.body).forEach(([key, val]) => {
    post[key] = val
  })

  const postId = await postRepository.save(post)
  ctx.body = { postId, post }
})
Вход в полноэкранный режим Выйти из полноэкранного режима

И последнее, но не менее важное, нам нужно удалить данные из базы данных, для этого мы создадим маршрут, который будет принимать параметр id в параметрах запроса для удаления только определенного поста:


router.delete('/post/:id', async (ctx) => {
  const postId = ctx.params.id
  const postRepository = client.fetchRepository(postSchema)
  await postRepository.remove(postId)
  ctx.body = { postId }
})
Вход в полноэкранный режим Выйти из полноэкранного режима

С CRUD мы закончили, теперь мы можем создать файл api entry, в котором мы настроим маршруты и установим соединение с базой данных.

// @/src/main.js
import Koa from 'koa'
import koaBody from 'koa-body'

import { router } from './routes.js'
import { createClient, client } from './db.js'

const startServer = async () => {
  const app = new Koa()
  await createClient()

  app.use(koaBody())
  app.use(router.routes())

  return app
}

startServer()
  .then(async (app) => {
    await new Promise(resolve => app.listen({ port: 3333 }, resolve))
  })
  .catch(async (err) => {
    console.error(err)
    await client.close()
    process.exit(1)
  })
Войти в полноэкранный режим Выход из полноэкранного режима

Как запустить

Чтобы запустить процесс api, выполните следующую команду:

npm run dev
Войти в полноэкранный режим Выйти из полноэкранного режима

Чтобы исправить форматирование кода, выполните следующую команду:

npm run lint
Войти в полноэкранный режим Выйти из полноэкранного режима

Заключение

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

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

Оцените статью
devanswers.ru
Добавить комментарий