📜 ⬆️ ⬇️

Automatically generated CMS using your ready-made GraphQL scheme

image

second version of GraphQL CMS

In my previous article, “ Well, Russian . Original ”, I told you how to cut your code and time in half if you use GraphQL with Mongoose.
')
Today we will also talk about GraphQL technology and if you work with it, this article will be able to help you save a decent amount of development time. The original article in English can be found on the link .

"Link to the module itself: graphql-auto-generating-cms .

As you may have guessed, this module uses your ready-made GraphQL scheme to generate a full-featured CMS. You will not need to spend a lot of time developing an administrative panel, and you will be able to concentrate more on the business processes of your project and on its architecture.

An important advantage of this module is that it does not require any changes from you in your ready-made code or project architecture, which makes its integration as simple as possible even on ready-made projects.

You have two ways to use this module.

  1. The first is as fast as possible and is suitable for a new project. All you need is a GraphQL scheme and a simple pattern following the name of GraphQL methods and types.

  2. And the second method that does not require you to follow any patterns, and can be easily integrated into an already finished project. All you need to do is provide the configuration object along with the GraphQL schema.

At the moment, the module does not support GraphQLList, nested objects and file downloads, their support will be implemented in future versions. At the moment, you can easily get around these limitations using self-written functions and components that you can add to the CMS, we will look at how to do this in this article.

Based on all the above, let's divide the current article into several points:


General rules


The module will use the graphQL type as an entity that will be available in the sidebar of the CMS.

To exclude types that are used only as nested objects. Accordingly, only those types that have one “Query” method and at least one “Mutation” method will be taken as an entity.

Each type can have only one “Query” [find], which will be used to get an array of objects, or to get one object using the “id” or “_id” argument depending on which type of database you use. A type can also have one or more of the following “Mutation” methods [create, update, remove].

Query method must support the following arguments:

{ offset: number, limit: number, id: number || _id: string //      } 

The arguments “offset” and “limit” will be used for pagination and to get data from the server in batches, and not to say to get 50t at once. objects because of what your application just hangs.

On the server side, this might look like this:

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

And the “id” argument will be used to get one instance. If you use a method like “findOne” to return one element using “id”, make sure that you return it inside the array, since the graphQL will expect exactly the array, even if it is one element.

Preparation for work

Installation:

 npm i -S graphql-auto-generating-cms 

On the server side, we need to run the middleware through which we will process the GrpahQL scheme, in the example below we will use the URL "/ graphql_cms_endpoint" as the end point:

 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.listen(port) 

After that we can use our React component on the client side. You can download it from a separate link or as a normal React component.

Inside the router:

 ... 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> 

Or as a component:

 <GraphqlCMS endpoint='/graphql_cms_endpoint' graphql='/graphql' /> 

In the endpoint property we specify the same URL that we used on the server side.

In the property "graphql" link to your GraphQL API.

The second option is well suited if you say you want to supplement CMS with authorization functions and so on. You simply paste it as a child component into the Layout with a navigation bar, authorization system and so on.

The first method of use, with a pattern


To use the quick way to generate your CMS, without additional configurations, you need to follow the following simple patterns in the GrpahQL name “Query” and “Mutation” methods.

 [graphql Type name]_[action] 

example:

 productType_find productType_create productType_update productType_remove 

Sorting menu items and input fields in the CMS will be identical to the order of the properties in the object.

For example, if in our scheme the following order of types:

 { productType: {}, userType: {}, categoryType: {}, ... } 

Then in the sidebar, the menu items will have the same order:

 productType userType categoryType 

The same applies to the order of type fields, their order will be taken as the basis for constructing a UI for a page viewing one instance of an element, or for adding a new element:

 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}, } }); 

Accordingly, if you want to change the order of the items in the sidebar, or change the order of the input fields, you just have to swap the properties in the GrpahQL scheme.

The second method of use, with a configuration object


The advantages of the second method:


Let's take a look at how it works, all you need to do is expand the configuration object on the server side. All fields except the “schema” are optional.

 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: {} } } } } 

Addition of CMS with its components and functions.


You can also add CMS menu items with your React components with additional features, say for some custom solutions, such as statistics or a general dashboard.

All you need to do is simply add another property 'newMenuItems' on the client side, to the component:

 <Route path='/graphql-cms' endpoint='/graphql_cms_endpoint' graphql='/graphql' newMenuItems={customPages} components={GraphqlCMS} /> 

Through which we send an array with additional menu items and components, the structure of the objects in the array is below:

 let customPages = [ { label: 'Custom Page', secret: 'uniqeForEachComponentSecret', view: { secret: 'sameUniqeComponentSecret', component: CustomDashboard //  React  } } ] 

The code above will look like this:



Thank you for your attention, I hope this module will be useful to you.

I am currently working on a new version of the module if you want to keep abreast of the “star” project on GitHub.
What will be included in the new version:


With the next update, the auto-generated CMS will satisfy 90% of your requirements for any CMS just using your GraphQL scheme!

" Example code
» Github

Several screenshots of the working version:





Source: https://habr.com/ru/post/314204/


All Articles