We decided that we're going to use a Headless CMS
as the backend API for our shop website.
And as the CMS we're going to use Strapi,
that is open source.
So in this video I'll give you a quick overview
by creating a new Strapi project.
Now, be aware that in the next video I will give you
a pre-populated project to download,
that already includes some data.
So this video is just an introduction
that you can watch without following
all the steps on your machine.
Anyway, I'm inside my Projects folder.
Now, we can create a new Strapi application
using the "create-strapi-app" tool,
and we can pass the name of the new project,
like "next-shop-backend",
and then the "--quickstart" option
so it will generate a project
with some default functionality.
After creating the project
it automatically started it
and also opened it in the browser.
Which is all very nice,
but I would rather stop it (with Ctrl+C)
so I can first show you a little bit
what's inside this project.
Let me open it in Visual Studio Code.
And you can see that there's a "package.json" file,
which means that this is a JavaScript project,
managed with npm.
If you look at the dependencies,
there are a bunch of "strapi" packages.
We don't really need to worry about the details.
What we want to do is start this app
in development mode, with "npm run develop".
This starts a local server,
that runs on port 1337.
The first thing we need to do
before we can use Strapi
is to create a user,
as in an administrator.
So I'm going to enter "Admin" as the "First name",
and "Strator" as the "Last name",
with "admin@example.com" for the "Email".
I'm just making up the details of course.
We also need a "Password"
that I'll set to "Admin123",
and then confirm the same password again.
And now we can submit.
Ok. So here we see the Strapi admin UI.
From here we can manage our data
and define how to expose it as an API.
Now, Strapi organises data in
what it calls "Collection Types".
You can think of a collection type
as a table in a database basically.
There is one predefined collection type
called "Users".
Pretty much all applications need some users.
Now, this collection is currently empty
but we can add a new user
simply by clicking this button.
We need a "Username", say "Alice",
then an "Email", like "alice@example.com",
and a password, that I'll set to "Alice123".
We can also set this user as "Confirmed",
otherwise they would need to verify their Email
before they can log in.
Let's "Save" the new user.
If we go back to the collection page,
we can now see "Alice" in the list.
Now, maybe you're wondering:
what's the difference between this user ("Alice")
and the Admin user we created
at the very beginning?
The users listed here are basically
the customers of our shop website.
They will be able to log into our frontend website,
once we implement authentication.
While the Admin user has access to
this backend administration panel.
So it's completely different kind of user.
Anyway, we'll talk more about users
when we get to the Authentication section.
What I want to show you now is that
we can also create our own collection types.
If we click "Create new collection type"
here we can choose a name,
for example we may want some Product items
to display on our shop website.
There are also some "Advanced Settings"
and here I'm going to disable the
"Draft/publish system".
What this means is that, if this is enabled,
when you add a new Product
it will initially be in "draft" state,
and then you need a second step to publish it.
This makes sense if you're publishing
articles for example,
where you want to save a draft first,
and then review it and publish it later.
But we don't need this two-step process
for our products.
So if we click "Continue",
here we can add some "field"
to our collection type.
Let's start with a simple "Text" field.
For each Product we'll want a "title",
that is the product name to display on our website.
And this can be a "Short text",
that's the pre-selected choice.
Now, let's add another field.
We may want a "description",
so that's another "Text" field.
But in this case we want it to be a "Long text".
Now, let's go and add yet another field.
This time we could use a "Number" field,
that's appropriate for the "price" of a Product.
Here we can select what kind of number it is.
For the "price" we want a "decimal" number.
Ok. Let's "Finish" here.
There are other fields we may want on a Product item,
but these 3 will do for this example.
So we can now "Save" this new collection type,
and this should restart the Strapi server.
Although sometimes I find that
I need to reload it manually.
In any case, you can see that now
under "Collection Types"
there is our new "Products" collection,
that is initially empty.
But we can add a new Product,
and here we get a form
with exactly the 3 fields we defined
for this collection type.
So we can enter a title,
like "First Product,
a description, like
"This is the first product."
And finally a price, say "10".
We didn't actually define a field for the currency,
but let's assume this means 10 dollars.
Anyway, let's save this new product.
And if we go back to the list,
we can see our "First Product" here.
Let me quickly add another item,
let's call it the "Second Product",
and after this I'll show you how
Strapi automatically exposes a REST API
that we can call to fetch this data.
That's the main advantage of using a Headless CMS.
To show you how that works
it's best if I use a REST client.
And I have one installed
as a Visual Studio Code extension.
It's literally called "REST Client",
if you want to install the same.
Otherwise you can use some other tool,
like Postman if you're familiar with that.
Now, the way this REST Client works
is that we create a new file in the editor,
set its language to "http",
and write API requests here,
like a GET request.
Then we need to pass the URL
for the Strapi server,
and we can request the products
by adding this path.
So Strapi automatically exposes
our Products collection as a REST API resource.
Now, the REST Client extension
allows us to send this request,
and we see the server response on the right.
Right now the response is "403 Forbidden",
and that's because we didn't configure
who can see these products.
If we go to "Settings",
down here where it says "users & permissions"
we want to configure the "Roles".
Strapi comes with two predefined roles:
"Authenticated" and "Public".
Now, if we select "Public",
we can configure the Permissions.
Here it shows our "Product" collection type,
but all the actions are deselected,
which means that right now
nobody can access the product data.
We want to enable the "find" action,
so we'll be able to "find", or list, the products.
And you can see on the right that "find"
corresponds to the "GET /products" route,
that is the path we just tried to request.
We could also enable "findone",
to request the details for a single product.
So "find" and "findone",
(along with "count") are read-only actions.
They let users read the data.
While "create", "delete" and "update"
obviously modify the data.
We typically want the "Public" role
to only be able to read the data.
So let's save these changes.
And at this point the "Public",
which effectively means any user,
should be able to get this list of products.
Let's try re-sending our request with the REST Client,
and you can see that this time
we get a "200 OK" response.
And the body is a JSON array
that contains our Product data.
Each Product object has the 3 fields we defined,
that are "title", "description", and "price".
But it also has an "id", that identifies each item
and is assigned automatically,
and then some "created_at"
and "updated_at" timestamps.
We can request a specific product,
but adding its "id" to the path.
And if we make this request,
you can see that the JSON response
contains a single object,
with the fields for the "First Product".
Of course if we request the product
with "id: 2" instead,
we'll get the data for the "Second Product".
So that's how Strapi works in a nut shell:
it lets us define some data types,
like a Product with certain fields.
It gives us a user interface that we can use
to insert and update that data.
And it automatically exposes that data as a REST API
that we can call from our own application.
Like, in our case we could fetch the product data
and display it on our shop website.