We're live-coding on Twitch! Join us!

Creating a Custom API with Strapi - A Node Headless CMS

Strapi is an amazing tool that lets us build our backends without writing a line of code. It comes with an API out of the box.

I would use Strapi as a Headless CMS because it allows for flexibility in content types. We could build a custom app whereas other CMSs are geared towards blogs.

While other Headless CMSs can be focused more on helping creating blogs (and that's perfectly fine), Strapi can be used to build more of an app than a blog. The ability to create all types of content is what gives Strapi this flexibility. We can also jump into the code of our Strapi installation and do more custom things like customizing our dashboard, making database queries, formatting content after an update, and programmatically sending emails.

The thing I love about Strapi is how easy it is to create your own custom APIs from whatever content you may have. Let's say we wanted to have a type of content called Pokemon. We could quickly build out our content fields and structure.

Let's dig into using Strapi.


There are a couple ways we can get started with Strapi.

  1. Create a Strapi installation locally. Push to a server later
  2. Create a Strapi installation on a server

If you wanted to work locally first, then you can create a Strapi application from the command line:

# with yarn
yarn create strapi-app my-strapi-project --quickstart

# or with npx
npx create-strapi-app my-strapi-project --quickstart

Using the --quickstart flag will make Strapi use SQLite for its database. If you don't use --quickstart, you should install a local database like MongoDB.

BeginnerTailwind.com Learn Tailwind CSS from Scratch

We'll be starting with a base Strapi installation on a DigitalOcean server. We have an article on how to quickly Install Strapi with 1-Click on DigitalOcean. We also have a video of installing Strapi on DigitalOcean.

Getting Started with Strapi

The Strapi Quick Start Guide and Tutorial are good places to start with Strapi. Let's walk through building something with Strapi in this tutorial.

Once you have Strapi installed either locally or on a server, you'll be able to see your new installation. At http://localhost:1337/ if working locally and at your new server's IP if working on a server.

We'll have to create a new admin account:

Once you create your new admin account, you'll see your new dashboard.

Notice that there are some Get Started Videos in the bottom right to give you some visual tutorials.

Let's look at what we'll build to familiarize ourselves with the Strapi dashboard.

What We'll Build

Lets build a small API that we will be able to use in our frontend applications. The overall flow of using Strapi would look like:

  1. Create content types
  2. Create content
  3. Use Strapi's API to grab content (use a frontend tool like Gatsby or Next.js)

Let's build a tiger listing app!

Seeing as how that Tiger King Netflix show is so popular, lets build a tiger tracking app.

Creating Our Content Type

We have to build our content type for a tiger. Let's add the following properties with these specific types:

  • name: Text
  • age: Number
  • weight: Number (in lbs)
  • length: Number (in inches)
  • location: Select

Let's start by creating the content type. Your dashboard will have a Create a Content-Type button when you start.

Once we've created a Tiger content type, we'll be able to add our properties via the dashboard. This name should always be singular.

Let's add a Text field and call it Name.

We can even click into advanced settings and make this a Required field.

We've been able to create a new content type, add it to our database, and generate relationships without ever writing a single line of code! We are able to use our coding skills to focus on the frontend code instead of worrying about the backend code.

Strapi Dashboard Updates Your Code

One of the cool things about Strapi is that you can use either this GUI dashboard or work within code to create your models and schema. If you are working locally, you can open up your files and see how this dashboard change has updated your code. You could keep your code in a GitHub repo, work locally, deploy to your DigitalOcean server, and that would be a great setup.

You'll find the changed files under /api. There is a new tiger folder for this content type we've created.

Open up tiger.settings.json and you can see our new Name attribute.

This connection also goes from code to dashboard. Let's add a new field from within our code:

"attributes": {
  "Name": {
    "type": "string",
    "required": true
  "Age": {
    "type": "integer"

Save this file and go to your dashboard and you'll see your new field called Age.

This is a cool feature of Strapi, that everything in the dashboard corresponds to a line in your code. For the most part, we can do all of our work from within the dashboard. You may want to jump into the code if you want to customize Strapi further.

Adding More Fields

Let's add the rest of our fields from our dashboard.

One of the interesting fields to add is Location. We can use an Enumeration field to create a dropdown of options.

Once we have all our fields, our dashboard will show this:

Feel free to add whatever fields you like. You can even create Components for a repeatable field.

Now that we have our content type created (make sure you hit Save), let's create some content.

Creating a Tiger

Click on Tigers in the left of our dashboard and click Add New Tiger.

Create a tiger!

Strapi even lets us configure how our dashboard looks. Try clicking Configure the view.

Strapi's REST API

Now that we've created some content, let's see how we could use it via an API. Strapi comes out of the box with a REST API.

We need to set our Tiger resource to have public permissions so that everyone can view these tigers. We won't provide public access to create Tigers though.

Click on Roles & Permissions in the left nav. Click on Public. Now we can check the following under Tiger:

  • find
  • findone

Hit save and we can view our API!

// if working locally

// if on a server 

Create more tigers and see them in your API! You can also grab a single Tiger by adding an ID to the end of your URL: http://localhost:1337/tigers/1

Adding GraphQL

We have the ability to use a REST API out of the box. What if we wanted to add a GraphQL API? Strapi provides this for us as well as a separate plugin. We have to add the GraphQL plugin.

If we click on Marketplace on the left side of our admin dashboard, we are able to see plugins we can add to our Strapi dashboard.

We can view our GraphQL endpoint at:

// if working locally

// if on a server 

Strapi comes with what they call a Shadow CRUD. It gives us type definition, queries, mutations, and resolvers for GraphQL based on our models (content-types).

If our model looks like this:

  "connection": "default",
  "options": {
    "timestamps": true
  "attributes": {
    "name": {
      "type": "string"
    "description": {
      "type": "text"
    "open": {
      "type": "boolean"

Our generated Shadow CRUD will look like this:

// Restaurant's Type definition
type Restaurant {
  _id: String
  created_at: String
  updated_at: String
  name: String
  description: String
  open: Boolean

// Queries to retrieve one or multiple restaurants.
type Query {
  restaurants(sort: String, limit: Int, start: Int, where: JSON): [Restaurant]
  restaurant(id: String!): Restaurant

// Mutations to create, update or delete a restaurant.
type Mutation {
  createRestaurant(input: createRestaurantInput): createRestaurantPayload!
  updateRestaurant(input: updateRestaurantInput): updateRestaurantPayload!
  deleteRestaurant(input: deleteRestaurantInput): deleteRestaurantPayload!

Going Further

Strapi docs are good at providing more code for every scenario. Here are some popular ones you may be interested in:

If you found Strapi helpful, check out our installation tutorial and let me know if you want to see more Strapi content.

Like this article? Follow @chris__sev on Twitter