Strapi tutorial : Getting Started

Juan Liberato
Aug 12, 2016 · 6 min read

Strapi (www.strapi.io) is a great tool for fast prototyping and creation of RESTful APIs , it features UI’s for the api administration and makes writing a API real fast.

In this tutorial we are going to install Strapi, configure a couple of endpoints and models and post to them.

Installing

Since strapi is uncompatible with node 6+ , make sure your node version is 5.9.1 (Or lower) before continuing, you can use the n utility to change the node version

Install n and strapi by :


sudo npm -g install n
sudo npm -g install strapi

Change node version before creating a strapi project and running strapi server

n 5.9.1strapi new test
cd test
strapi start

If you need stable node again just change it using n

n stable

Now the server must be living at http://localhost:1337

The admin panel will be available at :
http://localhost:1337/admin

Using the admin panel and the studio

The first time you start a strapi api, it will prompt you to add the api key from the studio to your app, go to the studio and under configuration , studio you should find a key generator to generate a secret key.

Secret key in the studio

Then copy that key under your ./config/studio.json , this all shall be easy.

Now you can create models and relations from the studio APIs panel.
For the purposes of this tutorial let’s create two API’s and call them parentapi and childrenapi

Now let’s explore the relationships of these APIs , click in Manage Relations to enter the relation editor.

Relationships in the API’s

You’ll see there are three relationships already created in the API, you can see these are CreatedBy , UpdatedBy and contributors. These allow you to define the relationship with the user model that is included with the framework. You can remove these relationships but they are very useful for authentication.

Each relationship in the API will create an attribute in the model linking to the model that is related, in many to many or many to one relationships an array will be created instead. So in a API that has the CreatedBy relationship you can access the user from the model by the CreatedBy attribute.

Let’s define a relationship between the father model and the children model by creating a relationship in the childrenapi called father, Check the object previews to see how relationships create the attributes in the other model

Remember to sync the studio and restart your strapi server everytime you make changes to the studio (Quit with ctrl-c and strapi start again)

The admin panel

If you enter the application in localhost:1337 you will be able to see a link to the admin panel or enter localhost:1337/admin , after creating an admin account for your application , you can explore the models that you created in the studio and the permissions under user in the sidebar.

Permission panel

The permission panel is your best friend , it will list the created routes for your application, per default the permissions are configured and you can post publicly , however we are going to set our new models to be created securely.

The contributor permission refers to a user that is in the contributor relationship of a model (has modified it at some point), i do not recommend using it for creating an instance of the model. Instead use the Registered permission to allow creating the instance securely from a user.

At this point we have created an api with 2 custom endpoints, user authentication and secured those endpoints (for creation) , wasn’t it kinda fast ?

Creating users and using our api’s

You can create users with the admin interface pretty easily , however we will forge the requests to show how a application shall do it. Use any http client you want for this section (such as postman which is very graphic), i use curl since it’s my favorite.

At this point you would have already created a user (admin) , let’s test how to login users with this admin.

To forge the login request , it shall go in the auth/local route of the app, it must be a POST request and in the body of the request you authenticate either with email or username in the identifier key

curl -H “Content-Type: application/json” -X POST -d ‘{“identifier”: “test”,”password”: “testtest”}’ http://localhost:1337/auth/local/

This request shall return a json web token that the front-end must use to communicate with the backend securely as well as the user info in a nice json.

{"jwt":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6W10sImZpbGVzQ3JlYXRlZCI6W10sInBhcmVudGFwaXMiOltdLCJjaGlsZHJlbmFwaXMiOltdLCJ1c2VybmFtZSI6InRlc3QiLCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJsYW5nIjoiZW5fVVMiLCJ0ZW1wbGF0ZSI6ImRlZmF1bHQiLCJpZF9yZWYiOiIxIiwicHJvdmlkZXIiOiJsb2NhbCIsInBhc3N3b3JkIjoiJDJhJDEwJG0xRE0zcHJwREhjZFg1OENqMlJRVS5QLkFNSTF5R1RmLnBHOE9kZGFSVXJITjNmSHl3YzZHIiwiaWQiOjEsImNyZWF0ZWRBdCI6IjIwMTYtMDgtMTFUMTM6NTQ6MDMuNzM2WiIsInVwZGF0ZWRBdCI6IjIwMTYtMDgtMTFUMTM6NTQ6MDMuNzQ2WiIsImlhdCI6MTQ3MDkyNDQ1MH0.8ZIEGOgj_ZPmwxmPuFuNVFWReGoFEeLWBBbTwEXTQe8","user":{"username":"test","email":"test@test.com","lang":"en_US","template":"default","id_ref":"1","provider":"local","id":1,"createdAt":"2016-08-11T13:54:03.736Z","updatedAt":"2016-08-11T13:54:03.746Z"}}

Create a user

Since the admin user has permissions for everything and we want to test our permissions, let’s create a new user without admin permission, i’ll call it testuser. This time we use the /auth/local/register route

curl -H “Content-Type: application/json” -X POST -d ‘{“username”: “testuser”,”email”: “test@user.com”,”password”: “slimshady”}’ http://localhost:1337/auth/local/register

Upon signup we get the same json that we get on login.

{"jwt":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6W10sImZpbGVzQ3JlYXRlZCI6W10sInBhcmVudGFwaXMiOltdLCJjaGlsZHJlbmFwaXMiOltdLCJ1c2VybmFtZSI6InRlc3R1c2VyIiwiZW1haWwiOiJ0ZXN0QHVzZXIuY29tIiwicGFzc3dvcmQiOiIkMmEkMTAkdmc1S094Z0NFcXZFdFI0Y2cwYXZoZUZFMG5JQUVmanZNd1hKZE84M2tWcmlidktjeURkR0siLCJpZF9yZWYiOiIxIiwibGFuZyI6ImVuX1VTIiwidGVtcGxhdGUiOiJkZWZhdWx0IiwicHJvdmlkZXIiOiJsb2NhbCIsImNyZWF0ZWRBdCI6IjIwMTYtMDgtMTJUMTQ6Mjg6MTguNzIxWiIsInVwZGF0ZWRBdCI6IjIwMTYtMDgtMTJUMTQ6Mjg6MTguNzIxWiIsImlkIjoyLCJpYXQiOjE0NzEwMTIxMzh9.IG6xMY5gpNWykT6CoXKIFrPo8SbkC4ygS71ppCeyjvM","user":{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2}}

Here we get the json web token (jwt) that we must use to forge authenticated requests, it can go either in the Bearer section fo the header, in the body as the token attribute (my personal favorite) or in the query string (i use it more for get requests.)

Creating a parentapi

Now let’s create a parent api using the routes that we can see in the permissions panel, this is very straightforward, just use the token in the body as an “token” attribute and post to the parent route

curl -H “Content-Type: application/json” -X POST -d ‘{“name”: “a parent ”, “token” : “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6W10sImZpbGVzQ3JlYXRlZCI6W10sInBhcmVudGFwaXMiOltdLCJjaGlsZHJlbmFwaXMiOltdLCJ1c2VybmFtZSI6InRlc3R1c2VyIiwiZW1haWwiOiJ0ZXN0QHVzZXIuY29tIiwicGFzc3dvcmQiOiIkMmEkMTAkdmc1S094Z0NFcXZFdFI0Y2cwYXZoZUZFMG5JQUVmanZNd1hKZE84M2tWcmlidktjeURkR0siLCJpZF9yZWYiOiIxIiwibGFuZyI6ImVuX1VTIiwidGVtcGxhdGUiOiJkZWZhdWx0IiwicHJvdmlkZXIiOiJsb2NhbCIsImNyZWF0ZWRBdCI6IjIwMTYtMDgtMTJUMTQ6Mjg6MTguNzIxWiIsInVwZGF0ZWRBdCI6IjIwMTYtMDgtMTJUMTQ6Mjg6MTguNzIxWiIsImlkIjoyLCJpYXQiOjE0NzEwMTIxMzh9.IG6xMY5gpNWykT6CoXKIFrPo8SbkC4ygS71ppCeyjvM”}’ http://localhost:1337/parentapi/

The response will be the new parentapi object

{"contributors":[{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2}],"childrenapi":[],"createdBy":{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2},"updatedBy":{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2},"name":"a parent ","template":"default","lang":"en_US","createdAt":"2016-08-12T14:38:13.502Z","updatedAt":"2016-08-12T14:38:13.509Z","id":1}

You can see that the relationships contributors , childrenapi and createdBy have all done their work since this object has them, our user who creates the object now is the CreatedBy and the contributors for this object. Also notice the id generated. (1 in this case.)

Creating a childrenapi

Lets now create a childrenapi for that parent object , to relate them use the “father” relationship we have previously created in the body of the request specifying the api.

curl -H “Content-Type: application/json” -X POST -d ‘{“father”:1,”name”: “testuser”}’ http://localhost:1337/childrenapi/

the server responds with :

{"message":"You are not allowed to perform this action."}

Ooops , always remember to use the token when accessing secure endpoints! (We just checked our api endpoint is secured!)

curl -H "Content-Type: application/json" -X POST -d '{"father":1,"name": "testuser", "token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6W10sImZpbGVzQ3JlYXRlZCI6W10sInBhcmVudGFwaXMiOltdLCJjaGlsZHJlbmFwaXMiOltdLCJ1c2VybmFtZSI6InRlc3R1c2VyIiwiZW1haWwiOiJ0ZXN0QHVzZXIuY29tIiwicGFzc3dvcmQiOiIkMmEkMTAkdmc1S094Z0NFcXZFdFI0Y2cwYXZoZUZFMG5JQUVmanZNd1hKZE84M2tWcmlidktjeURkR0siLCJpZF9yZWYiOiIxIiwibGFuZyI6ImVuX1VTIiwidGVtcGxhdGUiOiJkZWZhdWx0IiwicHJvdmlkZXIiOiJsb2NhbCIsImNyZWF0ZWRBdCI6IjIwMTYtMDgtMTJUMTQ6Mjg6MTguNzIxWiIsInVwZGF0ZWRBdCI6IjIwMTYtMDgtMTJUMTQ6Mjg6MTguNzIxWiIsImlkIjoyLCJpYXQiOjE0NzEwMTIxMzh9.IG6xMY5gpNWykT6CoXKIFrPo8SbkC4ygS71ppCeyjvM"}' http://localhost:1337/childrenapi/

This will create the desired childrenapi object and link it to the parent we specified in the relationship

{"contributors":[{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2}],"createdBy":{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2},"updatedBy":{"username":"testuser","email":"test@user.com","id_ref":"1","lang":"en_US","template":"default","provider":"local","createdAt":"2016-08-12T14:28:18.721Z","updatedAt":"2016-08-12T14:28:18.721Z","id":2},"father":{"name":"a parent ","createdBy":2,"updatedBy":2,"template":"default","lang":"en_US","createdAt":"2016-08-12T14:38:13.502Z","updatedAt":"2016-08-12T14:38:13.509Z","id":1},"name":"testuser","template":"default","lang":"en_US","createdAt":"2016-08-12T14:41:15.388Z","updatedAt":"2016-08-12T14:41:15.393Z","id":1}

See the parent object in the father attribute related to the relationship we created.

Now you are set to explore your recently created objects in the admin and create more, check the strapi docs for more clarity on strapi. http://strapi.io/documentation

Juan Liberato

Written by

Software engineer, loves the educational industry, researcher in stat models for education

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade