Автоматично генерується CMS використовую вашу готову GraphQL схему

image
У моїй попередній статті "ну Російській. Оригинал" я розповідав як можна вдвічі скоротити свій код і час, якщо ви використовуєте GraphQL разом з Mongoose.
Сьогодні мова також піде про технології GraphQL і якщо ви працюєте з нею то ця стаття зможе допомогти вам зберегти пристойну кількість часу на розробку. Оригінал статті англійською ви можете найту ссылке.
Посилання на сам модуль: graphql-auto-generating-cms.
Як ви вже напевно здогадалися даний модуль використовує вашу готову GraphQL схему для генерації повнофункціональної CMS. Вам не потрібно буде витрачати купу часу на розробку адміністративної панелі, і ви зможете більше зосередитися на бізнес-процесах вашого проекту і на його архітектурі.
Важливою перевагою даного модуля є те, що він не вимагає від вас ніяких змін у вашому готовому коді або архітектурі проекту, що робить його інтеграцію максимально простим навіть на вже готових проектах.
У вас є два способи використовувати даний модуль.
  1. Перший максимально швидкий і підійде для нового проекту. Від вас вимагається тільки GraphQL схема і дотримання легкому паттерну по найменуванню GraphQL методів і типів.
  2. другий спосіб, який не вимагає від вас дотримуватися ніяких патернів, і може бути легко інтегрований у вже готовий проект. Все що від вас потрібно надати конфігураційний об'єкт разом з GraphQL схемою.
На даний момент модуль не підтримує GraphQLList, вкладені об'єкти і завантаження файлів, їх підтримка буде реалізована в майбутніх версіях. На даний момент ви можете легко обійти ці обмеження використовуючи самописні функції та компоненти якими ви можете доповнити CMS, ми розглянемо як це зробити в даній статті.
Виходячи з усього вище перерахованого давайте розділимо поточну статтю на кілька пунктів:
  • Загальні правила
  • Підготовка до роботи
  • Перший спосіб використання, з паттерном
  • Другий спосіб використання, з конфігураційним об'єктом
  • Додаток CMS своїми компонентами і функціями

Загальні правила

Модуль буде використовувати graphQL тип як сутність яка буде доступна в бічному меню CMS.
Щоб виключити типи які використовуються тільки як вкладені об'єкти. Відповідно за сутність будуть взяті тільки ті типи в яких є один "Query" метод і хоча б один "Mutation" метод.
Кожен тип може мати тільки один "Query" [find], який буде використовуватися для отримання масиву об'єктів, або для отримання одного об'єкта з використанням аргументу "id" або "_id" залежно який тип бази даних ви використовуєте. Так само тип може мати один або декілька з наступних "Mutation" методів [create, update, remove].
Query метод повинен обов'язково підтримувати такі аргументи:
{
offset: number,
limit: number,
id: number || _id: string // в залежності від вашого сховища
}

Аргументи "offset" і "limit" будуть використані для нумерації сторінок і що б отримувати дані з сервера по порціях, а не скажемо відразу отримати 50т. об'єктів із за чого ваш додаток просто зависне.
На серверній стороні це може виглядати наступним чином:
let {offset, limit} = args; 

return new Promise((resolve, reject) => {
Ingredients.find(query).skip(offset).limit(limit).exec((err, res) => err ? reject(err) : resolve(res));
});

І аргумент "id" буде використаний, щоб отримати один примірник. Якщо ви будете використовувати метод кшталт "findOne", щоб повернути один елемент використовуючи "id", переконайтеся, що ви повернете його всередині масиву, так як graphQL буде очікувати саме масив, навіть якщо це один елемент.
Підготовка до роботи

Установка:
npm i -S graphql-auto-generating-cms

На серверній стороні ми повинні запустити middleware через яке будемо обробляти GrpahQL схему, у прикладі нижче ми будемо використовувати URL "/graphql_cms_endpoint" в якості кінцевої точки:
...
import express from 'express';
import graphqlCMS from 'graphql-auto-generating-cms/lib/middleware';
import schema from '../schema';
const printSchema = require('graphql/utilities/schemaPrinter').printSchema;
let app = express();

let config = {schema: printSchema(schema)}
app.use('/graphql_cms_endpoint', graphqlCMS(config));
...
app.слухати(port)

Після цього ми можемо використовувати наш React компонент на клієнтській стороні. Ви можете завантажити його за окремою посиланням або як звичайний React компонент.
Всередині роутера:
...
import GraphqlCMS from 'graphql-auto-generating-cms';

export default (
<Router onUpdate={() => window.scrollTo(0, 0)} history={browserHistory}>
<Route
path='/graphql-cms'
endpoint='/graphql_cms_endpoint'
graphql='/graphql'
components={GraphqlCMS}
/>
...
</Router>

в якості компонента:
<GraphqlCMS
endpoint='/graphql_cms_endpoint'
graphql='/graphql'
/>

У властивості "endpoint" ми вказуємо той же URL, який ми використовували на серверній стороні.
Властивості "graphql" посилання на ваш GraphQL API.
Другий варіант добре підходить якщо ви скажімо хочете доповнити CMS функціями авторизації і тп. Ви просто зміните його дочірній компонент в Layout з навігаційною панеллю, системою авторизації і тп.
Перший спосіб використання, з паттерном

Щоб використовувати швидкий спосіб генерації вашої CMS, без додаткових конфігурацій, вам потрібно слідувати наступному простому патерни у найменуванні GrpahQL "Query" і "Mutation" методи.
[graphql Type name]_[action]

приклад:
productType_find
productType_create
productType_update
productType_remove

Сортування пунктів меню і input полів в CMS буде ідентично порядку властивостей в об'єкті.
Наприклад: якщо в нашій схемі наступний порядок типів:
{
productType: {},
userType: {},
categoryType: {},
...
}

у бічній панелі, пункти меню будуть мати той же порядок:
productType
userType
categoryType

Те ж саме відноситься до порядку полів типів, їх порядок буде взято за основу побудови UI сторінки перегляду одного примірника елемента, або для додавання нового елемента:

let productType = new GraphQLObjectType({
name: 'productType',
fields: {
_id: {type: GraphQLString},
title: {type: GraphQLString},
shortDescription: {type: GraphQLString},
price: {type: GraphQLString},
isPublished: {type: GraphQLBoolean},
createdAt: {type: GraphQLString},
updatedAt: {type: GraphQLString},
bulletPoints: {type: GraphQLString},
scienceShort: {type: GraphQLString},
scienceFull: {type: GraphQLString},
}
});

Відповідно якщо ви хочете змінити порядок пунктів у бічному меню, або поміняти порядок input полів, ви просто повинні поміняти місцями властивості GrpahQL схемою.
Другий спосіб використання, з конфігураційним об'єктом

Переваги другого способу:
  • Вам не потрібно вносити ніякі зміни в поточний код і/або архітектуру
  • Не обов'язково використовувати naming патерн
  • Ви можете заборонити будь-які «Mutation» методи для кожного типу
  • Ви можете змінити спосіб сортування полів і бічного меню, без зміни в схемі, просто міняючи порядок правил властивості «rules»
  • Ви можете задавати довільну назву пунктів бічного меню, і всіх полів. Спочатку в якості назв пунктів меню будуть використані імена graphQL типів, і як назва полів, буде використано назву властивостей типу
  • Ви можете заборонити редагування будь-яких полів
  • Ви можете задати довільно які властивості будуть використовуватися всередині таблиці зі списком документів. Спочатку для поля [#/ID] буде використано властивість «id» або "_id" типу, і як [title] буде використано друге властивість GraphQL типу
  • Ви можете змінювати яке поле потрібно використовувати для конкретного властивості, наприклад використовувати input або textarea, змінити тип input, скажімо на «date» і тп
Давайте розглянемо як це працює, все що вам для цього потрібно, розширити конфігураційний об'єкт на серверній стороні. Всі поля крім "schema" не обов'язкові до використання.
let config = {schema: printSchema(schema)}
app.use('/graphql_cms_endpoint', graphqlCMS(config));

let config = {
schema: printSchema(schema), 
// ваша "printed" схема [required]

exclude: ['paymentType', 'invoiceType'], 
//graphql типи які ви хочете виключити з CMS

rules: {
// дерево правил для кожного або деяких типів graphQL

categoryType: { 
// ім'я вашого graphQL типу

label: 'Categories', 
// кастомное ім'я яке буде використано у боків меню

listHeader: {
// дані з цієї властивості використовуються для таблиці об'єктів
// перший стовпець [id] і другий [title] 
// ви можете використовувати одну або декілька властивостей для кожного стовпця
// UI вони будуть відображатися як "String" + "" + "String"

id: ['id'],
title: ['description']
},

resolvers: {
// якщо ви не хочете використовувати naming патерн
// ви повинні вказати ім'я для кожного 
// Query's і Mutation's методу для даного типу

find: {
resolver: 'getCategories' 
// Query method name
},
create: {
resolver: 'addCategory'
// Mutation method name

allowed: true
},
update: {
resolver: 'updateCategory'
// Mutation method name

allowed: true
},
remove: {
allowed: false
// якщо ви не хочете надавати доступ
// до цього методу з боку клієнта
// ви можете його заборонити, вказавши true 
// кром "find", його не можна заборонити
}
},
fields: {
_id: {}, 
sortNumber: {
label: 'custom field name to show in UI',
inputControl: 'input', 
// can be "input" or "textarea"

inputType: 'number', 
// can be any input type: date, text, file etc.

disabled: true, 
// заборонити редагування даного поля

exclude: false, 
// приховати дане поле в CMS
},
name: {}, 
// ви також можете використовувати порожній об'єкт
// скажімо якщо ви хочете просто відсортувати елементи

createdAt: {},
updatedAt: {},
isPublished: {}
}
}
}
}

Додаток CMS своїми компонентами і функціями

Ви також можете доповнити пункти меню CMS своїми React компоненти з додатковими функціями, скажімо для якихось кастомних рішень, таких як статистика або загальний dashboard.
Все що для цього потрібно просто додати ще одну властивість 'newMenuItems' на клієнтській стороні, до компоненту:
<Route
path='/graphql-cms'
endpoint='/graphql_cms_endpoint'
graphql='/graphql'
newMenuItems={customPages}
components={GraphqlCMS}
/>

Через яке ми відправляємо масив з додатковими пунктами меню і компонентами, структура об'єктів у масиві нижче:

let customPages = [
{
label: 'Custom Page',
secret: 'uniqeForEachComponentSecret',
view: {
secret: 'sameUniqeComponentSecret',
component: CustomDashboard // Ваш React компонент
}
}
]

Код вище буде виглядати наступним чином:

Спасибі за увагу, сподіваюся даний модуль буде вам корисний.
Щоб бути в курсі оновлень або нових функцій, ви можете додати проект вибрані, на GitHub.
example code
GitHub
Кілька скріншотів робочої версії:





Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.