Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Хранение данных на сервере

Список в памяти сервера пропадает при каждом перезапуске. Чтобы статьи сохранялись, их нужно где-то хранить. В Nuxt для этого есть встроенное хранилище Nitro — useStorage. Это хранилище «ключ — значение»: под строковым ключом лежит любое значение, которое можно записать в JSON. Хранилище подключается к разным местам — папке на диске, Redis, облаку; в курсе используется папка на диске.

Настройка

Опишите хранилище в nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  compatibilityDate: '2025-07-15',
  nitro: {
    storage: {
      blog: { driver: 'fs', base: './.data/blog' }
    }
  }
})

Хранилище получило имя blog, драйвер fs пишет данные в файлы, base — папка для них. Добавьте строку .data в файл .gitignore, чтобы данные не попали в git, и перезапустите npm run dev.

Чтение и запись

// server/api/visits.get.ts
export default defineEventHandler(async () => {
  const storage = useStorage('blog')
  const visits = ((await storage.getItem<number>('visits')) ?? 0) + 1
  await storage.setItem('visits', visits)
 
  return { visits }
})

getItem читает значение по ключу (или null, если его нет), setItem записывает. Обновляйте /api/visits — число растёт и не сбрасывается после перезапуска сервера: оно лежит в файле .data/blog/visits.

Статьи на диске

Замените server/utils/posts.ts:

// server/utils/posts.ts
export interface Post {
  id: number
  title: string
  text: string
}
 
export interface PostComment {
  author: string
  text: string
}
 
export async function getPosts() {
  return (await useStorage('blog').getItem<Post[]>('posts')) ?? []
}
 
export async function savePosts(posts: Post[]) {
  await useStorage('blog').setItem('posts', posts)
}

Теперь обработчики берут статьи через эти функции:

// server/api/posts.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody<{ title?: string; text?: string }>(event)
 
  if (!body.title || !body.text) {
    throw createError({ statusCode: 400, message: 'Заполните заголовок и текст' })
  }
 
  const posts = await getPosts()
  const post = {
    id: Math.max(0, ...posts.map((p) => p.id)) + 1,
    title: body.title,
    text: body.text
  }
  posts.push(post)
  await savePosts(posts)
 
  setResponseStatus(event, 201)
  return post
})

В server/api/posts.get.ts и server/api/posts/[id].get.ts замените обращение к массиву posts строкой const posts = await getPosts() и сделайте обработчики async. Добавленные статьи переживут перезапуск.

Комментарии

Комментарии каждой статьи храните под своим ключом. Тип PostComment описан выше в server/utils/posts.ts:

// server/api/posts/[id]/comments.get.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  return (await useStorage('blog').getItem<PostComment[]>(`comments:${id}`)) ?? []
})
// server/api/posts/[id]/comments.post.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  const body = await readBody<{ author?: string; text?: string }>(event)
 
  if (!body.author || !body.text) {
    throw createError({ statusCode: 400, message: 'Укажите имя и текст' })
  }
 
  const storage = useStorage('blog')
  const comments = (await storage.getItem<PostComment[]>(`comments:${id}`)) ?? []
  comments.push({ author: body.author, text: body.text })
  await storage.setItem(`comments:${id}`, comments)
 
  setResponseStatus(event, 201)
  return comments
})

Ключ с двоеточием comments:1 драйвер fs превращает в файл .data/blog/comments/1. Список комментариев первой статьи — по адресу /api/posts/1/comments.

Когда нужна настоящая база данных

Хранилище «ключ — значение» хорошо для небольшого блога. Если нужны поиск по полям, связи и много записей, подключают базу данных — SQLite, PostgreSQL или MySQL — через её библиотеку для Node.js. Обращаются к ней так же из обработчиков в server/.

Частая ошибка

Вызвать useStorage('blog'), не описав хранилище в nitro.storage. Ошибки не будет, но Nitro поместит такие данные в память, и после перезапуска они пропадут. Если данные исчезают, проверьте настройку и перезапустите сервер после правки nuxt.config.ts.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.