1
00:00:03,000 --> 00:00:06,698
We decided that we're going to use a Headless CMS

2
00:00:06,698 --> 00:00:09,718
as the backend API for our shop website.

3
00:00:09,718 --> 00:00:12,813
And as the CMS we're going to use Strapi,

4
00:00:12,813 --> 00:00:14,323
that is open source.

5
00:00:14,323 --> 00:00:17,871
So in this video I'll give you a quick overview

6
00:00:18,673 --> 00:00:21,146
by creating a new Strapi project.

7
00:00:21,146 --> 00:00:25,043
Now, be aware that in the next video I will give you

8
00:00:25,043 --> 00:00:27,741
a pre-populated project to download,

9
00:00:27,741 --> 00:00:30,139
that already includes some data.

10
00:00:30,139 --> 00:00:32,912
So this video is just an introduction

11
00:00:32,912 --> 00:00:35,610
that you can watch without following

12
00:00:35,610 --> 00:00:37,859
all the steps on your machine.

13
00:00:38,808 --> 00:00:41,616
Anyway, I'm inside my Projects folder.

14
00:00:42,116 --> 00:00:44,973
Now, we can create a new Strapi application

15
00:00:44,973 --> 00:00:47,298
using the "create-strapi-app" tool,

16
00:00:47,864 --> 00:00:50,449
and we can pass the name of the new project,

17
00:00:50,449 --> 00:00:51,918
like "next-shop-backend",

18
00:00:52,476 --> 00:00:54,316
and then the "--quickstart" option

19
00:00:54,816 --> 00:00:56,646
so it will generate a project

20
00:00:56,646 --> 00:00:58,664
with some default functionality.

21
00:01:01,316 --> 00:01:02,948
After creating the project

22
00:01:02,948 --> 00:01:04,641
it automatically started it

23
00:01:04,641 --> 00:01:06,775
and also opened it in the browser.

24
00:01:07,400 --> 00:01:08,878
Which is all very nice,

25
00:01:08,878 --> 00:01:11,448
but I would rather stop it (with Ctrl+C)

26
00:01:12,012 --> 00:01:14,438
so I can first show you a little bit

27
00:01:14,438 --> 00:01:16,257
what's inside this project.

28
00:01:16,824 --> 00:01:18,897
Let me open it in Visual Studio Code.

29
00:01:19,890 --> 00:01:23,253
And you can see that there's a "package.json" file,

30
00:01:23,253 --> 00:01:26,286
which means that this is a JavaScript project,

31
00:01:26,286 --> 00:01:27,406
managed with npm.

32
00:01:27,406 --> 00:01:29,516
If you look at the dependencies,

33
00:01:29,516 --> 00:01:32,087
there are a bunch of "strapi" packages.

34
00:01:32,087 --> 00:01:35,252
We don't really need to worry about the details.

35
00:01:36,081 --> 00:01:38,831
What we want to do is start this app

36
00:01:38,831 --> 00:01:42,192
in development mode, with "npm run develop".

37
00:01:42,768 --> 00:01:45,264
This starts a local server,

38
00:01:45,264 --> 00:01:47,389
that runs on port 1337.

39
00:01:47,981 --> 00:01:49,852
The first thing we need to do

40
00:01:49,852 --> 00:01:51,400
before we can use Strapi

41
00:01:51,400 --> 00:01:52,690
is to create a user,

42
00:01:52,690 --> 00:01:54,173
as in an administrator.

43
00:01:54,866 --> 00:01:57,641
So I'm going to enter "Admin" as the "First name",

44
00:01:58,141 --> 00:02:00,214
and "Strator" as the "Last name",

45
00:02:00,714 --> 00:02:03,686
with "admin@example.com" for the "Email".

46
00:02:03,686 --> 00:02:06,658
I'm just making up the details of course.

47
00:02:07,230 --> 00:02:08,901
We also need a "Password"

48
00:02:08,901 --> 00:02:10,774
that I'll set to "Admin123",

49
00:02:11,341 --> 00:02:13,548
and then confirm the same password again.

50
00:02:15,074 --> 00:02:16,411
And now we can submit.

51
00:02:18,106 --> 00:02:21,512
Ok. So here we see the Strapi admin UI.

52
00:02:21,512 --> 00:02:24,307
From here we can manage our data

53
00:02:24,307 --> 00:02:27,625
and define how to expose it as an API.

54
00:02:28,300 --> 00:02:30,419
Now, Strapi organises data in

55
00:02:30,419 --> 00:02:32,832
what it calls "Collection Types".

56
00:02:32,832 --> 00:02:35,317
You can think of a collection type

57
00:02:35,317 --> 00:02:37,875
as a table in a database basically.

58
00:02:38,594 --> 00:02:41,312
There is one predefined collection type

59
00:02:41,312 --> 00:02:42,358
called "Users".

60
00:02:42,358 --> 00:02:45,494
Pretty much all applications need some users.

61
00:02:45,494 --> 00:02:48,211
Now, this collection is currently empty

62
00:02:48,920 --> 00:02:50,372
but we can add a new user

63
00:02:50,372 --> 00:02:52,172
simply by clicking this button.

64
00:02:52,730 --> 00:02:55,104
We need a "Username", say "Alice",

65
00:02:55,604 --> 00:02:58,730
then an "Email", like "alice@example.com",

66
00:02:59,230 --> 00:03:02,540
and a password, that I'll set to "Alice123".

67
00:03:03,396 --> 00:03:06,169
We can also set this user as "Confirmed",

68
00:03:06,169 --> 00:03:09,346
otherwise they would need to verify their Email

69
00:03:09,346 --> 00:03:10,901
before they can log in.

70
00:03:11,536 --> 00:03:13,008
Let's "Save" the new user.

71
00:03:14,169 --> 00:03:16,075
If we go back to the collection page,

72
00:03:16,575 --> 00:03:19,022
we can now see "Alice" in the list.

73
00:03:19,022 --> 00:03:20,980
Now, maybe you're wondering:

74
00:03:20,980 --> 00:03:24,406
what's the difference between this user ("Alice")

75
00:03:24,406 --> 00:03:26,433
and the Admin user we created

76
00:03:26,433 --> 00:03:27,971
at the very beginning?

77
00:03:27,971 --> 00:03:30,418
The users listed here are basically

78
00:03:30,418 --> 00:03:32,795
the customers of our shop website.

79
00:03:32,795 --> 00:03:36,361
They will be able to log into our frontend website,

80
00:03:36,361 --> 00:03:38,668
once we implement authentication.

81
00:03:38,668 --> 00:03:41,045
While the Admin user has access to

82
00:03:41,045 --> 00:03:43,422
this backend administration panel.

83
00:03:43,422 --> 00:03:46,358
So it's completely different kind of user.

84
00:03:46,358 --> 00:03:48,805
Anyway, we'll talk more about users

85
00:03:48,805 --> 00:03:51,742
when we get to the Authentication section.

86
00:03:53,151 --> 00:03:55,402
What I want to show you now is that

87
00:03:55,402 --> 00:03:58,233
we can also create our own collection types.

88
00:03:58,798 --> 00:04:01,372
If we click "Create new collection type"

89
00:04:01,872 --> 00:04:03,310
here we can choose a name,

90
00:04:03,810 --> 00:04:06,731
for example we may want some Product items

91
00:04:06,731 --> 00:04:08,887
to display on our shop website.

92
00:04:09,456 --> 00:04:11,631
There are also some "Advanced Settings"

93
00:04:12,131 --> 00:04:14,434
and here I'm going to disable the

94
00:04:14,434 --> 00:04:16,040
"Draft/publish system".

95
00:04:16,040 --> 00:04:19,112
What this means is that, if this is enabled,

96
00:04:19,112 --> 00:04:20,927
when you add a new Product

97
00:04:20,927 --> 00:04:23,580
it will initially be in "draft" state,

98
00:04:23,580 --> 00:04:26,791
and then you need a second step to publish it.

99
00:04:26,791 --> 00:04:29,374
This makes sense if you're publishing

100
00:04:29,374 --> 00:04:30,841
articles for example,

101
00:04:30,841 --> 00:04:33,424
where you want to save a draft first,

102
00:04:33,424 --> 00:04:36,216
and then review it and publish it later.

103
00:04:37,345 --> 00:04:39,817
But we don't need this two-step process

104
00:04:39,817 --> 00:04:40,894
for our products.

105
00:04:41,458 --> 00:04:42,862
So if we click "Continue",

106
00:04:43,362 --> 00:04:45,145
here we can add some "field"

107
00:04:45,145 --> 00:04:46,609
to our collection type.

108
00:04:47,173 --> 00:04:49,646
Let's start with a simple "Text" field.

109
00:04:50,146 --> 00:04:52,560
For each Product we'll want a "title",

110
00:04:52,560 --> 00:04:55,798
that is the product name to display on our website.

111
00:04:56,361 --> 00:04:58,335
And this can be a "Short text",

112
00:04:58,335 --> 00:05:00,309
that's the pre-selected choice.

113
00:05:00,872 --> 00:05:02,546
Now, let's add another field.

114
00:05:03,046 --> 00:05:04,731
We may want a "description",

115
00:05:04,731 --> 00:05:06,596
so that's another "Text" field.

116
00:05:07,212 --> 00:05:10,539
But in this case we want it to be a "Long text".

117
00:05:11,039 --> 00:05:13,379
Now, let's go and add yet another field.

118
00:05:13,879 --> 00:05:16,153
This time we could use a "Number" field,

119
00:05:16,653 --> 00:05:19,512
that's appropriate for the "price" of a Product.

120
00:05:20,012 --> 00:05:23,138
Here we can select what kind of number it is.

121
00:05:23,638 --> 00:05:26,379
For the "price" we want a "decimal" number.

122
00:05:26,879 --> 00:05:28,511
Ok. Let's "Finish" here.

123
00:05:28,511 --> 00:05:32,115
There are other fields we may want on a Product item,

124
00:05:32,115 --> 00:05:34,631
but these 3 will do for this example.

125
00:05:35,266 --> 00:05:38,274
So we can now "Save" this new collection type,

126
00:05:38,774 --> 00:05:41,182
and this should restart the Strapi server.

127
00:05:42,474 --> 00:05:44,488
Although sometimes I find that

128
00:05:44,488 --> 00:05:46,435
I need to reload it manually.

129
00:05:47,002 --> 00:05:49,133
In any case, you can see that now

130
00:05:49,133 --> 00:05:50,683
under "Collection Types"

131
00:05:51,247 --> 00:05:53,559
there is our new "Products" collection,

132
00:05:53,559 --> 00:05:54,982
that is initially empty.

133
00:05:55,541 --> 00:05:57,564
But we can add a new Product,

134
00:05:57,564 --> 00:05:59,099
and here we get a form

135
00:05:59,099 --> 00:06:01,610
with exactly the 3 fields we defined

136
00:06:01,610 --> 00:06:03,354
for this collection type.

137
00:06:04,063 --> 00:06:05,793
So we can enter a title,

138
00:06:05,793 --> 00:06:07,233
like "First Product,

139
00:06:07,805 --> 00:06:09,063
a description, like

140
00:06:09,063 --> 00:06:10,915
"This is the first product."

141
00:06:11,481 --> 00:06:13,676
And finally a price, say "10".

142
00:06:13,676 --> 00:06:17,406
We didn't actually define a field for the currency,

143
00:06:17,406 --> 00:06:20,258
but let's assume this means 10 dollars.

144
00:06:20,904 --> 00:06:22,877
Anyway, let's save this new product.

145
00:06:23,704 --> 00:06:25,426
And if we go back to the list,

146
00:06:25,426 --> 00:06:27,491
we can see our "First Product" here.

147
00:06:28,048 --> 00:06:29,603
Let me quickly add another item,

148
00:06:30,103 --> 00:06:32,126
let's call it the "Second Product",

149
00:06:32,626 --> 00:06:35,187
and after this I'll show you how

150
00:06:35,187 --> 00:06:38,308
Strapi automatically exposes a REST API

151
00:06:38,308 --> 00:06:41,189
that we can call to fetch this data.

152
00:06:41,849 --> 00:06:45,496
That's the main advantage of using a Headless CMS.

153
00:06:45,996 --> 00:06:47,692
To show you how that works

154
00:06:47,692 --> 00:06:49,843
it's best if I use a REST client.

155
00:06:50,408 --> 00:06:51,972
And I have one installed

156
00:06:51,972 --> 00:06:54,187
as a Visual Studio Code extension.

157
00:06:54,752 --> 00:06:56,863
It's literally called "REST Client",

158
00:06:56,863 --> 00:06:58,739
if you want to install the same.

159
00:06:59,297 --> 00:07:01,618
Otherwise you can use some other tool,

160
00:07:01,618 --> 00:07:04,182
like Postman if you're familiar with that.

161
00:07:04,743 --> 00:07:07,011
Now, the way this REST Client works

162
00:07:07,011 --> 00:07:09,861
is that we  create a new file in the editor,

163
00:07:10,425 --> 00:07:12,532
set its language to "http",

164
00:07:13,691 --> 00:07:16,060
and write API requests here,

165
00:07:16,060 --> 00:07:17,668
like a GET request.

166
00:07:18,252 --> 00:07:20,089
Then we need to pass the URL

167
00:07:20,089 --> 00:07:21,532
for the Strapi server,

168
00:07:22,718 --> 00:07:25,128
and we can request the products

169
00:07:25,128 --> 00:07:26,683
by adding this path.

170
00:07:26,683 --> 00:07:29,092
So Strapi automatically exposes

171
00:07:29,092 --> 00:07:32,745
our Products collection as a REST API resource.

172
00:07:33,478 --> 00:07:35,404
Now, the REST Client extension

173
00:07:35,404 --> 00:07:37,393
allows us to send this request,

174
00:07:37,957 --> 00:07:40,615
and we see the server response on the right.

175
00:07:41,115 --> 00:07:44,123
Right now the response is "403 Forbidden",

176
00:07:44,623 --> 00:07:46,914
and that's because we didn't configure

177
00:07:46,914 --> 00:07:48,541
who can see these products.

178
00:07:49,101 --> 00:07:50,322
If we go to "Settings",

179
00:07:51,667 --> 00:07:54,311
down here where it says "users & permissions"

180
00:07:54,811 --> 00:07:56,867
we want to configure the "Roles".

181
00:07:58,211 --> 00:08:01,253
Strapi comes with two predefined roles:

182
00:08:01,253 --> 00:08:03,515
"Authenticated" and "Public".

183
00:08:04,092 --> 00:08:05,647
Now, if we select "Public",

184
00:08:05,647 --> 00:08:07,547
we can configure the Permissions.

185
00:08:08,104 --> 00:08:10,788
Here it shows our "Product" collection type,

186
00:08:10,788 --> 00:08:12,923
but all the actions are deselected,

187
00:08:13,484 --> 00:08:15,167
which means that right now

188
00:08:15,167 --> 00:08:17,433
nobody can access the product data.

189
00:08:17,997 --> 00:08:20,411
We want to enable the "find" action,

190
00:08:20,411 --> 00:08:23,762
so we'll be able to "find", or list, the products.

191
00:08:24,329 --> 00:08:26,776
And you can see on the right that "find"

192
00:08:26,776 --> 00:08:29,283
corresponds to the "GET /products" route,

193
00:08:29,844 --> 00:08:32,654
that is the path we just tried to request.

194
00:08:33,154 --> 00:08:35,596
We could also enable "findone",

195
00:08:35,596 --> 00:08:39,062
to request the details for a single product.

196
00:08:39,062 --> 00:08:40,952
So "find" and "findone",

197
00:08:41,609 --> 00:08:45,050
(along with "count") are read-only actions.

198
00:08:45,050 --> 00:08:47,371
They let users read the data.

199
00:08:47,371 --> 00:08:50,332
While "create", "delete" and "update"

200
00:08:50,332 --> 00:08:52,412
obviously modify the data.

201
00:08:52,412 --> 00:08:55,213
We typically want the "Public" role

202
00:08:55,213 --> 00:08:57,853
to only be able to read the data.

203
00:08:58,753 --> 00:09:00,659
So let's save these changes.

204
00:09:01,619 --> 00:09:03,503
And at this point the "Public",

205
00:09:03,503 --> 00:09:05,508
which effectively means any user,

206
00:09:05,508 --> 00:09:08,182
should be able to get this list of products.

207
00:09:08,803 --> 00:09:12,263
Let's try re-sending our request with the REST Client,

208
00:09:12,763 --> 00:09:14,978
and you can see that this time

209
00:09:14,978 --> 00:09:16,971
we get a "200 OK" response.

210
00:09:17,544 --> 00:09:19,566
And the body is a JSON array

211
00:09:19,566 --> 00:09:21,804
that contains our Product data.

212
00:09:21,804 --> 00:09:25,270
Each Product object has the 3 fields we defined,

213
00:09:25,270 --> 00:09:28,519
that are "title", "description", and "price".

214
00:09:28,519 --> 00:09:32,129
But it also has an "id", that identifies each item

215
00:09:32,129 --> 00:09:34,295
and is assigned automatically,

216
00:09:35,155 --> 00:09:37,068
and then some "created_at"

217
00:09:37,068 --> 00:09:39,127
and "updated_at" timestamps.

218
00:09:39,700 --> 00:09:42,092
We can request a specific product,

219
00:09:42,092 --> 00:09:44,343
but adding its "id" to the path.

220
00:09:44,913 --> 00:09:46,284
And if we make this request,

221
00:09:47,246 --> 00:09:49,412
you can see that the JSON response

222
00:09:49,412 --> 00:09:51,004
contains a single object,

223
00:09:51,004 --> 00:09:53,552
with the fields for the "First Product".

224
00:09:54,179 --> 00:09:56,684
Of course if we request the product

225
00:09:56,684 --> 00:09:58,186
with "id: 2" instead,

226
00:09:58,757 --> 00:10:01,615
we'll get the data for the "Second Product".

227
00:10:02,115 --> 00:10:05,425
So that's how Strapi works in a nut shell:

228
00:10:05,425 --> 00:10:08,104
it lets us define some data types,

229
00:10:08,104 --> 00:10:10,861
like a Product with certain fields.

230
00:10:10,861 --> 00:10:14,328
It gives us a user interface that we can use

231
00:10:14,328 --> 00:10:16,770
to insert and update that data.

232
00:10:16,770 --> 00:10:20,868
And it automatically exposes that data as a REST API

233
00:10:20,868 --> 00:10:24,177
that we can call from our own application.

234
00:10:24,177 --> 00:10:28,038
Like, in our case we could fetch the product data

235
00:10:28,038 --> 00:10:30,795
and display it on our shop website.

