APIs in less than 5 minutes with Strapi

By May 7, 2020JAMstack

APIs in less than 5 minutes with Strapi

This is an updated version of the original post authored by Omkar Joshi.

The evolution of CDN (Content Delivery Networks) and business need to scale multi-channel ways of interacting with the customer have made the traditional CMS obsolete. Organizations are using JAMstack to build responsive websites & CDN to deliver them where the customer is. With the evolution of the 5G and data-intensive applications such as AR, VR, drones, etc. new technologies will emerge that will deliver services closest to where the customer resides.

One of the key components in this JAMStack based architecture is a headless CMS system. Strapi is an open-source headless CMS framework to build APIs with minimum efforts and in almost no time. In this tutorial, we will build a simple headless CMS with Strapi and create API endpoints in less than 5 minutes. In the next tutorial, we will explore GraphQL and how to use it with Strapi.

Prerequisites

You will need the NodeJS version 12.x, NPM version 6.x and MongoDB > 3.6 installed on your machine if you plan to follow along with the tutorial. You can use Docker image for Mongo or run it locally. Strapi also supports MariaDB, MySQL, and PostgreSQL but as of this writing, MongoDB is supported as a first-class citizen. Therefore, for the scope of this article, we’ll stick to MongoDB. Strapi works well with MacOS and Linux based operating systems and for Windows, it has some support via WSL.

Creating The First Project

Once the node and NPM is setup, we’re ready to create our very first project using Strapi. Create the project by running npx create-strapi-app:

$ npx create-strapi-app mongoose-project
npx: installed 84 in 12.217s
Creating a new Strapi application at /home/omkar/strapi/mongoose-project.

? Choose your installation type Custom (manual settings)
? Choose your default database client mongo
? Database name: mongoose-project
? Host: 127.0.0.1
? +srv connection: false
? Port (It will be ignored if you enable +srv): 27017
? Username: strapiuser
? Password: *******
? Authentication database (Maybe "admin" or blank): 
? Enable SSL connection: No

Select the appropriate options. In this case, I’ve selected a custom installation with MongoDB as the database. Since MongoDB is running locally on my machine, the host IP is that of the localhost and other configurations are defaults. Setup will proceed and connect to MongoDB:

Creating a project with custom database options.
Creating files.
Dependencies installed successfully.

Your application was created at /home/omkar/strapi/mongoose-project.

Available commands in your project:

  npm run develop
  Start Strapi in watch mode.

  npm run start
  Start Strapi without watch mode.

  npm run build
  Build Strapi admin panel.

  npm run strapi
  Display all available commands.

You can start by doing:

  cd /home/omkar/strapi/mongoose-project
  npm run develop

Let’s change the directory to the newly created project and verify the information provided while creating the project in a database.json file:

$ cd mongoose-project
$ cat config/environments/development/database.json

Starting The Strapi Instance

We are now ready to start the Strapi with MongoDB as it’s backend:

$ npm run develop

> mongoose-project@0.1.0 develop /home/omkar/strapi/mongoose-project
> strapi develop

Building your admin UI with development configuration ...

✔ Webpack
  Compiled successfully in 18.02s

[2020-03-29T09:52:07.174Z] info File created: /home/omkar/strapi/mongoose-project/extensions/users-permissions/config/jwt.json

 Project information                                                          

┌────────────────────┬──────────────────────────────────────────────────┐
│ Time               │ Sun Mar 29 2020 15:22:07 GMT+0530 (India Standa… │
│ Launched in        │ 2288 ms                                          │
│ Environment        │ development                                      │
│ Process PID        │ 1457109                                          │
│ Version            │ 3.0.0-beta.19.3 (node v12.15.0)                  │
└────────────────────┴──────────────────────────────────────────────────┘

 Actions available                                                            

One more thing...
Create your first administrator 💻 by going to the administration panel at:

┌─────────────────────────────┐
│ http://localhost:1337/admin │
└─────────────────────────────┘

[2020-03-29T09:52:07.211Z] debug HEAD /admin (18 ms) 200
[2020-03-29T09:52:07.215Z] info ⏳ Opening the admin panel...

When you open the admin panel for the first time, you need to create a new user via the registration page:
Strapi admin user creationAfter creating the new user, Strapi will automatically log you in.Strapi home

Users – The Users Permissions Plugin

Before we move on to create our first entity, let’s take a look at the Users tab that we see on the left-hand panel. This tab comes from a plugin called users-permissions. In a nutshell, this plugin provides, in the increasing level of abstraction, permissions, roles, and users for us to work with. Permissions can be fine-grained and we can restrict the permission precisely to a specific action for a specific entity. A set of these permissions can be associated with a role that can then be applied to multiple users.

If you click on the “Users” tab, you’ll see the no users there. Strapi registers the first user as an administrator (the one we registered at the beginning). Administrators can be managed by going to ‘Manage the administrators’ section, which can be found under your name at top right. The “Roles & Permissions” tab on the left provides the interface necessary to create roles, permissions, etc.

Strapi adminCreating The First Content-Type

To create a content-type or an entity, click on the ‘Content-Type Builder’ from left pane then click on ‘Create new collection type’. In this blog, I am creating 2 collection types, Article, and Author. After creating collection types, add appropriate fields in those.

  • The article collection type can have fields like the title (Text), contents (Text), publishDate (Datetime) etc.
  • The author collection type can have fields like a name (Text), designation (Text), etc.

Add CollectionAlong with this, we also need to create many to many relationships between author and article since one article could be written by more than one author and one author can write multiple articles. We can achieve this by adding a field in either author or article of type relation and then by selecting the type of relation as many to many.

Collection RelationshipWe can perform CRUD operations on the created content types from the UI. However, since we’ve already created these content types, we can use REST APIs to perform these operations. The documentation (swagger) plugin enables easy consumption of the APIs created for the entity types.

Swagger – The Documentation Plugin

Let’s install the documentation plugin. To do so, we need to go to the ‘Marketplace’ section from the left-hand side pane. Find the Documentation plugin and click on Download. Install Documentation

On the left-hand side panel, under plugins, we should now be able to see the documentation option. When we click on that, we see a few options like the jwt token, the link to open the documentation, the button to update the documentation, etc. Clicking on open the documentation will take us to the documentation page. Here we can get the details of the content types that we have created and a simple mechanism to test and consume those content types.Documentation Plugin

 

Before we can try out the APIs, we need to authorize the swagger client. We can do so by clicking on the authorize button on the right-hand side of the documentation page and adding the jwt token from the documentation plugin. After doing so, we can start using the swagger client from the documentation page.

Now that we have a Strapi server running, we can create content types (entities or models) in virtually no time. This allows us great flexibility to work on the user interface side without worrying much about the backend. These endpoints can be consumed by any frontend applications via HTTP REST.

Diving Deeper into Strapi

We’ve seen that Strapi generates some code that allows us to perform CRUD operations. But where does that code reside? In the project directory, we can see that there is a directory called api. In this directory, Strapi will create a new directory for each of the content type (model) that we create. For example, in our case, there are 2 directories, article, and author:

$ cd api/
$ ls 
article  author

In each of those directories, we can find the code specific to those entities.

$ ls article/
config  controllers  documentation  models  services

In the config directory which will find the routes.json file, which is useful for finding out the code for a specific end-point. Example routes.json file for the article entity is shown below.

{
  "routes": [
    {
      "method": "GET",
      "path": "/articles",
      "handler": "Article.find",
      "config": {
        "policies": []
      }
    },
    {
      "method": "GET",
      "path": "/articles/count",
      "handler": "Article.count",
      "config": {
        "policies": []
      }
    },
    {
      "method": "GET",
      "path": "/articles/:_id",
      "handler": "Article.findOne",
      "config": {
        "policies": []
      }
    },
    ...
    ]
}

The above file has been shortened for brevity. The documentation directory contains the generated files used by the documentation plugin to show the Swagger UI.

In models, controllers, and services directories, we will find a structure similar to that of config. We will have a directory per entity within which the generated code will reside. The entity directories under models will also have a settings.json file within them. This file will be named as <Modelname>.settings.json. It contains the details about that entity and the attributes that belong to that entity, including the related attributes. One needs to be careful in making changes to the related attributes. Since Strapi will not work if the relationship attributes in both related entities do not match in type. The article.settings.json has been added as an example. Beyond what the UI can provide – these files can be directly edited if needed for specific use cases.

{
  "kind": "collectionType",
  "connection": "default",
  "collectionName": "Article",
  "info": {
    "name": "Article"
  },
  "options": {
    "increments": true,
    "timestamps": true
  },
  "attributes": {
    "title": {
      "type": "string"
    },
    "contents": {
      "type": "text"
    },
    "publishDate": {
      "type": "date"
    },
    "authors": {
      "collection": "author",
      "via": "articles",
      "dominant": true
    }
  }
}

File Upload – Working with files

One of the crucial things for any CMS system is the file upload functionality. Strapi comes with a built-in file upload plugin. On the left-hand panel, there’s an option for file upload called ‘Media Library’. It provides an interface for uploading the file. These files are placed in the directory <project_dir>/public/uploads.Strapi Uploads

Next Steps

Strapi allows us to quickly build models without worrying about the backend side of things. While this itself is a great value addition, one of the best things about Strapi is its support of GraphQL. Strapi provides a GraphQL Plugin and Playground allows us to use GraphQL queries with the models that we’ve created. In the next article, we will cover GraphQL queries in the context of Strapi.

Bhavin Gandhi

Author Bhavin Gandhi

Bhavin is working as a Software Engineer with InfraCloud where he is working on tools around container orchestration and related areas. Bhavin's main area of interest are Free and Open Source software, containers and Kubernetes.

More posts by Bhavin Gandhi

Leave a Reply