1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/gfzl-open-source-vue-koa2

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Vue-Koa2 сервер

Vue2, Koa2 и Mongo: создание блога для одного пользователя

Структура каталога

  • app.js — входной файл;
  • models — модели базы данных;
  • controllers — контроллеры для выполнения логических операций;
  • middlewares — собственные промежуточные программы;
  • routes — маршрутизация;
  • utils — функции утилит;
  • configs — файлы конфигурации;
  • package.json — список необходимых зависимостей проекта.

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

Использование класса и async/await для написания контроллеров

Объединение класса и async/await позволяет лучше организовать логику API, делая её более понятной и структурированной. Это избавляет от необходимости писать отдельную функцию для обработки логики и экспортировать её. Вместо этого можно просто экспортировать класс. Функции async могут использоваться как статические методы класса, что позволяет обращаться к этим контроллерам через className.[xxx].

Вот пример кода:

# Логический слой (из server/controllers/article.js)
const Article = require('../models/article.js');
class ArticleController {
    // Создание статьи
    static async createArticle(ctx, next) { ... }
    // Публикация статьи
    static async ifPublishArticle(ctx) { ... }
    // Удаление статьи по ID
    static async deleteArticleById(ctx) { ... }
    // Изменение статьи
    static async modifyArticle(ctx) { ... }
    // Получение всех статей
    static async getAllArticles(ctx) { ... }
    // Получение опубликованных статей
    static async getAllPublishedArticles(ctx) { ... }
}
exports = module.exports = ArticleController;
# Интерфейс слоя (из server/routes/index.js)
// Импорт класса
const A = require('../controllers/article.js');
router
    .get('/articles/:id', A.getArticleById)
    .post('/articles', checkToken, A.createArticle)
    .delete('/articles/:id', checkToken, A.deleteArticleById)
    .patch('/articles/:id', checkToken, A.modifyArticle)
    .get('/allArticles', checkToken, A.getAllArticles)
    .get('/articles', A.getAllPublishedArticles)
    .patch('/pubArticles/:id', checkToken, A.ifPublishArticle)
    .post('/tags', checkToken, T.createTag)
    .get('/tags', T.getAllTags)
    .patch('/tags/:id', checkToken, T.modifyTag)
    .delete('/tags/:id', checkToken, T.deleteTag);

Как использовать Koa2 с ES6/7 для создания высококачественных Restful API — подробная версия.

Аутентификация с использованием JSON Web Token

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

Пример кода:

# Пример (из server/routes/index.js)
router
    // Модификация отдельного тега
    .patch('/tags/:id', checkToken, T.modifyTag)
    // Удаление отдельного тега
    .delete('/tags/:id', checkToken, T.deleteTag);

В этом коде видно, что для изменения тега необходимо пройти через промежуточное программное обеспечение checkToken. Без прохождения через это промежуточное ПО операция модификации невозможна. Код аутентификации находится в файлах server/middlewares/checkToken.js и server/utils/index.js.

Создание единого промежуточного программного обеспечения для обработки ответов

Зачем создавать единое промежуточное ПО для обработки ответов? Это ПО просто добавляет ещё один уровень к ctx.body, предоставляя возможность настраивать статусные коды ошибок и обеспечивая единообразие формата данных, отправляемых клиенту.

// Используется для предоставления унифицированных ответов — унифицированное промежуточное ПО для ответов — должно использоваться перед другими промежуточными ПО
// Добавление методов к объекту ctx для успешного ответа
module.exports = async (ctx, next) => {
    // Успешный ответ
    ctx.success = ({ data, msg, total, success }) => {
        ctx.body = { code: 200, data, msg, total, success };
    };
    await next();
};

Форматирование дат в статьях

Форматирование дат может быть выполнено с использованием moment и mongoose. Виртуальные свойства mongoose позволяют настроить формат даты.

# Форматирование даты
const moment = require('moment');
moment.locale('zh-cn');
// Необходимо сначала установить, а затем получить
articleSchema.set('toJSON', { getters: true, virtuals: true });
articleSchema.set('toObject', { getters: true, virtuals: true });
articleSchema.path('createTime').get(function(v) {
  return moment(v).format('YYYY MMMM Do, h:mm:ss a');
});
articleSchema.path('lastEditTime').get(function(v) {
  return moment(v).format('YYYY MMMM Do, h:mm:ss a');
});

При сохранении даты в контроллере используется new Date(), а при извлечении данных mongoose автоматически форматирует дату с помощью виртуальных свойств.

Mongoose и ссылки

MongoDB — это NoSQL база данных. Mongoose позволяет использовать ссылки на другие документы.

const articleSchema = new Schema({
    .....
    tags: [{ type: Schema.Types.ObjectId, ref: 'tag' }] // type — это идентификатор документа tag
});

Здесь articleSchema определяет поле tags как массив, содержащий идентификаторы документов tag. При использовании population для извлечения данных можно получить более подробную информацию о связанных документах. ``` .exec()

Тогда мы получим { title: 'Заголовок', ..., tags: ['Тег1', 'Тег2']}, а не просто tagId.
[Изучение Mongoose на продвинутом уровне](https://cnodejs.org/topic/5206581b44e76d216aae072e)

## Разбиение на страницы
В настоящее время при поиске статей обычно не возвращаются все статьи сразу, а осуществляется поиск по частям.
Для блогов с небольшим объёмом данных я напрямую использую параметры запроса page и limit для поиска статей. Например, www.xxx.com/api?page=1&&limit=5 для запроса данных первой страницы, по 5 элементов на каждой странице.

```javascript
 let page = +ctx.query.page;
let limit = +ctx.query.limit || 5;
result = await Article
                .find()
                .sort({ 'createTime': -1 })
                .skip(limit * (page - 1))
                .limit(limit)
                .populate('tags')
                .exec()
                .catch(err => {
                    ctx.throw(500, 'Внутренняя ошибка сервера — ошибка разбиения на страницы!');
                });

Если вы хотите выполнить дальнейшую оптимизацию, ознакомьтесь со следующей статьёй Оптимизация разбиения MongoDB на страницы

Пользовательская конфигурация

# Можно создать файл private.js в каталоге configs для настройки. Формат объекта должен быть согласованным.
let config = {
   admin: {
       username: 'admin',           
       password: 'admin'
   },
   jwt: {
       secret: 'secret',            
       expiresIn: '3600s'          //в секундах
   },
   mongodb: {
       host: '127.0.0.1',
       database: 'blog',
       port: 27017,
       user: '',                    //необязательно
       password: ''                 //необязательно
   },
   app: {
       port: process.env.PORT || 3000,
       routerBaseApi: '/api'
   }
};

Комментарии ( 0 )

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

Введение

**Блог для одного пользователя, созданный с использованием vue2, koa2 и mongo.** *Примечание: без уточнения контекста запроса перевод может быть неполным.* Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/gfzl-open-source-vue-koa2.git
git@api.gitlife.ru:oschina-mirror/gfzl-open-source-vue-koa2.git
oschina-mirror
gfzl-open-source-vue-koa2
gfzl-open-source-vue-koa2
master