GraphQL, Rich Text Editor & Redesigned Dashboard are released on npm!

🚀 GraphQL

Requesting a REST API can quickly become complex especially if you have to deal with relations. Furthermore, even though the client only needs few fields, REST APIs send every single property of each entity. This involves important performance issues, in particular for mobile applications used with low-speed networks.

For these reasons, in 2015, Facebook published GraphQL: a brand new query language for APIs.

Over the last past two years, GraphQL has been growing at a vertiginous speed. Giant companies like Yelp, Spotify, Github, Walmart and NYTimes already published a GraphQL API. The trend on Google speaks for itself:

Even if REST is still the most used convention, GraphQL quickly became the most wanted feature on the Vote page.

Implementation

As you probably know, APIs generated with Strapi are, by default, REST APIs. The idea with this plugin was to add a new layer to easily request the API using GraphQL, without breaking the existing endpoints.

To implement GraphQL, we created a new plugin named graphql which creates a new endpoint /graphql and the GraphiQL interface.

Permissions

In a Strapi project, API security rules can easily be managed thanks to the Users & Permissions plugin. It works as well with GraphQL. The rules (also named policies) are associated to a controller’s action. When you’re making a query with GraphQL, you’re hitting the same controller’s actions as you were doing with the REST endpoints.

Let’s take an example, the GET /post endpoint call the same logic than the following GraphQL Query:

query {

posts {

title

content

}

}

Both will execute the find action in the Post.js controller.

// Post.js

module.exports = {



find: async (ctx) => {

return strapi.services.post.fetchAll(ctx.query);

},



...

}

It makes our permissions layer compatible with the REST endpoint and the GraphQL query as well.

By default, the GraphQL queries are secured, you need to be authenticated by sending the Authorization header with the request see the React-Apollo example. Otherwise, you can make the queries available to everyone or allow the access using the administration panel (Users & Permissions > Roles > Public > Application).

Usage

To get started with GraphQL in your app, please install the plugin first. To do that, open your terminal and run the following command:

strapi install graphql

Then, start your app and open your browser at http://localhost:1337/graphiql. You should see the interface (GraphiQL) that will help you to write GraphQL queries to explore your data.

Configurations

By default, the Shadow CRUD feature is enabled and the GraphQL is set to /graphql . You can edit these configurations in the following file.

Path — ./plugins/graphql/config/settings.json .

{

"endpoint": "/graphql",

"shadowCRUD": true

}

Query API

In the section, we assume that the Shadow CRUD feature is enabled. For each model, the plugin auto-generates queries which just fit your needs.

Fetch a single entry

query {

user(id: "5aafe871ad624b7380d7a224") {

username

email

}

}

Fetch multiple entries

query {

users {

username

email

}

}

Filters

You can also apply different parameters to create more complex queries.

limit (integer): Define the number of returned entries.

(integer): Define the number of returned entries. start (integer): Define the number of entries to skip.

(integer): Define the number of entries to skip. sort (string): Define how the data should be sorted.

(string): Define how the data should be sorted. where (object): Define the filters to apply in the query.

(object): Define the filters to apply in the query. <field> : Equals.

: Equals. <field>_ne : Not equals.

: Not equals. <field>_lt : Lower than.

: Lower than. <field>_lte : Lower than or equal to.

: Lower than or equal to. <field>_gt : Greater than.

: Greater than. <field>_gte : Lower than or equal to.

: Lower than or equal to. <field>_contains : Contains.

: Contains. <field>_containss : Contains sensitive.

Return the second decade of users which have an email that contains @strapi.io ordered by username.

query {

users(limit: 10, start: 10, sort: "username:asc", where: {

email_contains: "@strapi.io"

}) {

username

email

}

}

Return the users which have been created after the March, 19th 2018 4:21 pm.

query {

users(where: {

createdAt_gt: "2018-03-19 16:21:07.161Z"

}) {

username

email

}

}

Shadow CRUD

To simplify and automate the build of the GraphQL schema, we introduced the Shadow CRUD feature. It automatically generates the type definition, queries and resolvers based on your models. The feature also lets you make a complex query with many arguments such as limit , sort , start and where .

Example

If you’ve generated an API called Post using the CLI strapi generate:api post or the administration panel, your model looks like this:

Path — ./api/post/models/Post.settings.json .

{

"connection": "default",

"options": {

"timestamps": true

},

"attributes": {

"title": {

"type": "string"

}

"content": {

"type": "text"

},

"published": {

"type": "boolean"

}

}

}

The generated GraphQL type and queries will be:

type Post {

_id: String

created_at: String

updated_at: String

title: String

content: String

published: Boolean

}



type Query {

posts(sort: String, limit: Int, start: Int, where: JSON): [Post]

post(id: String!): Post

}

The query will use the generated controller’s actions as resolvers. It means that the posts query will execute the Post.find action and the post query will use the Post.findOne action.

Go further

Of course, you can fully customise the GraphQL schema: take a look at the documentation to add new types, execute policies before a resolver, link a query to a controller action, define a custom resolver, apply permissions on a query, disable (or depreciate) a query/type, etc.

Want to give it a try with React? Check out the example app using React & Apollo.

This version only supports queries. Mutations and subscriptions will be released in the next few months. That being said, pull requests are welcomed.

🚀 Rich Text Editor

If you use Strapi to manage content, you probably need to edit blocks of text through a Rich Text Editor.

With more than 240 votes on the Vote page, the commonly called “WYSIWYG” (What You See Is What You Get) editor, jumped on the top of our priorities.

Markdown syntax

Two syntaxes are commonly used by Rich Text Editors: HTML and Markdown.

HTML is the well-known language which powered every single page on the web. It is undeniably the most powerful way to write rich content, but the syntax may sometimes look heavy for basic stuff.

A great alternative is Markdown: a lightweight markup language with plain text formatting syntax, which can be easily converted into HTML. This language is trusted by many editors, CMS and companies, like GitHub. Since it is more lightweight than HTML (but can still contain HTML for section requiring a specific format) we chose it for the brand new Rich Text Editor.

The text is stored in the database as Markdown and exposed by your Strapi API in the same format. We advise you to use a node module such as Showdown to convert it into HTML in your frontend.

Draft

Since we had specific requirements and will add features in the future, the Rich Text Editor had to be entirely customizable. We benchmarked many existing open source WYSIWYG editors and finally went for Draft to create our own.

Draft is a Rich Text Editor framework for React. Its main advantage is the level of customization it offers. It has been built as a framework instead of a heavy editor, it lets developers add very specific behaviours.

Upload

Content Management is not only about text, but also about media.

Any content block may include assets, such as images or videos. Because file upload is already handled by Strapi, we used it to extend the capabilities of this new WYSIWYG. Files can be added with a simple drag and drop, browsing or pasting.

Preview & full-screen mode

Editing is necessary. Previewing is handy.

Markdown is an easy to learn syntax. The only trouble is that you need to preview what you are writing. Don’t worry, we added an easy to use preview mode, so you can see what your content actually looks like.

Bonus! We added a full-screen mode to let you comfortably edit content.

🚀 New Dashboard Design

Last but not least, we entirely reviewed the design of the home page of the dashboard. From now, it looks much better and several useful informations are displayed through three sections.