1
00:00:02,000 --> 00:00:03,000
Okay, so now we also know how

2
00:00:03,000 --> 00:00:07,000
to work with our API routes inside of getStaticProps.

3
00:00:07,000 --> 00:00:09,000
We don't send the request there,

4
00:00:09,000 --> 00:00:13,000
we just execute the code directly in getStaticProps

5
00:00:13,000 --> 00:00:16,000
or getServiceAddProps.

6
00:00:16,000 --> 00:00:20,000
Now let's talk about dynamic API routes.

7
00:00:20,000 --> 00:00:21,000
What's that?

8
00:00:21,000 --> 00:00:26,000
Well, let's say you don't just wanna have /api/feedback

9
00:00:26,000 --> 00:00:28,000
which handles post and get requests,

10
00:00:28,000 --> 00:00:33,000
but you also wanna support /api/feedback/some feedback ID

11
00:00:35,000 --> 00:00:37,000
to just fetched a single piece

12
00:00:37,000 --> 00:00:41,000
of data for that specific feedback item,

13
00:00:41,000 --> 00:00:44,000
because maybe you need that somewhere on your page.

14
00:00:44,000 --> 00:00:48,000
For example, on the feedback page, you could say that

15
00:00:48,000 --> 00:00:50,000
for every list item you're rendering here,

16
00:00:50,000 --> 00:00:55,000
you also have like a show details button.

17
00:00:55,000 --> 00:00:56,000
And when that button is clicked,

18
00:00:56,000 --> 00:01:00,000
you wanna show the details for that feedback item.

19
00:01:00,000 --> 00:01:02,000
And hence you want to fetch the data,

20
00:01:02,000 --> 00:01:05,000
the full data for that feedback item.

21
00:01:05,000 --> 00:01:06,000
Now we are

22
00:01:06,000 --> 00:01:09,000
of course actually fetching the full feedback data here.

23
00:01:09,000 --> 00:01:12,000
And we could just use client inside JavaScript

24
00:01:12,000 --> 00:01:16,000
to use that already loaded data for that.

25
00:01:16,000 --> 00:01:20,000
But let's assume that we're not fetching the full data here,

26
00:01:20,000 --> 00:01:22,000
but that instead we are only getting the ID

27
00:01:22,000 --> 00:01:25,000
and the text and not the email address.

28
00:01:25,000 --> 00:01:27,000
And therefore when this button is clicked,

29
00:01:27,000 --> 00:01:29,000
we wanna fetch the full data again,

30
00:01:29,000 --> 00:01:32,000
but not for all feedback items,

31
00:01:32,000 --> 00:01:35,000
but for this single feedback item.

32
00:01:35,000 --> 00:01:39,000
And that's what you could use a dynamic API route for,

33
00:01:39,000 --> 00:01:42,000
because we already know dynamic pages

34
00:01:42,000 --> 00:01:44,000
where you create a page with

35
00:01:44,000 --> 00:01:49,000
that square bracket notation, like this.

36
00:01:49,000 --> 00:01:51,000
This would then allow

37
00:01:51,000 --> 00:01:56,000
for a request sent to /feedback/some-id.

38
00:01:56,000 --> 00:01:58,000
And some-id would be interpreted

39
00:01:58,000 --> 00:02:02,000
as a value for this ID placeholder

40
00:02:02,000 --> 00:02:06,000
and you could then use it inside of that page component

41
00:02:06,000 --> 00:02:07,000
and so on.

42
00:02:07,000 --> 00:02:10,000
That's what we already learned before.

43
00:02:10,000 --> 00:02:12,000
Now that's for regular pages.

44
00:02:12,000 --> 00:02:16,000
We can use a similar feature for API routes,

45
00:02:16,000 --> 00:02:19,000
because it's also not unrealistic

46
00:02:19,000 --> 00:02:23,000
that we wanna send the request to /api/feedback

47
00:02:23,000 --> 00:02:26,000
and then the ID of a specific feedback

48
00:02:26,000 --> 00:02:30,000
to then load the data for that specific feedback.

49
00:02:30,000 --> 00:02:33,000
And for this, we need a new file because here

50
00:02:33,000 --> 00:02:36,000
in feedback.js, we only handle the requests

51
00:02:36,000 --> 00:02:40,000
to /api/feedback/nothing.

52
00:02:40,000 --> 00:02:42,000
Hence in the API folder,

53
00:02:42,000 --> 00:02:46,000
we can add a dynamic API route and we do that

54
00:02:46,000 --> 00:02:50,000
in exactly the same way as we do it for a regular pages.

55
00:02:50,000 --> 00:02:54,000
We use square brackets and then any place holder name

56
00:02:54,000 --> 00:02:59,000
of our choice, like for example id or feedbackId

57
00:02:59,000 --> 00:03:00,000
or whatever you want.

58
00:03:00,000 --> 00:03:03,000
And I'll go with feedbackId.

59
00:03:03,000 --> 00:03:07,000
So now we have a dynamic API route file.

60
00:03:07,000 --> 00:03:10,000
In there, we still define our handler function

61
00:03:10,000 --> 00:03:12,000
and we still export that.

62
00:03:12,000 --> 00:03:14,000
So just as in the other file,

63
00:03:14,000 --> 00:03:17,000
because it works in exactly the same way.

64
00:03:17,000 --> 00:03:20,000
This API route works in exactly the same way,

65
00:03:20,000 --> 00:03:21,000
it's just dynamic.

66
00:03:21,000 --> 00:03:24,000
So for dynamic path segments.

67
00:03:24,000 --> 00:03:28,000
So therefore in here, we might now want to fetch the data

68
00:03:28,000 --> 00:03:30,000
for a specific piece of feedback.

69
00:03:30,000 --> 00:03:31,000
And for that of course,

70
00:03:31,000 --> 00:03:36,000
we need to know which concrete value was encoded

71
00:03:36,000 --> 00:03:41,000
in the URL as a value for this placeholder.

72
00:03:41,000 --> 00:03:42,000
And we can get access

73
00:03:42,000 --> 00:03:46,000
to that again, through this request object

74
00:03:46,000 --> 00:03:50,000
which we should accept together with that response object.

75
00:03:50,000 --> 00:03:52,000
And there, we learned that we have body

76
00:03:52,000 --> 00:03:55,000
for accessing the submitted data,

77
00:03:55,000 --> 00:03:58,000
method for finding out which kind of request it was.

78
00:03:58,000 --> 00:04:01,000
And we also have query for getting access

79
00:04:01,000 --> 00:04:05,000
to query parameters and regular parameters.

80
00:04:05,000 --> 00:04:09,000
So we can get access and get our feedbackId

81
00:04:10,000 --> 00:04:13,000
by accessing req.query.feedbackId,

82
00:04:14,000 --> 00:04:18,000
.feedbackId because I encoded feedbackId

83
00:04:18,000 --> 00:04:21,000
between the square brackets here in my file name.

84
00:04:22,000 --> 00:04:25,000
So that gives us access to the concrete feedbackId

85
00:04:25,000 --> 00:04:28,000
that was part of the URL

86
00:04:28,000 --> 00:04:31,000
when that request hit that handler.

87
00:04:31,000 --> 00:04:33,000
And now we can use that feedbackId

88
00:04:33,000 --> 00:04:36,000
to retrieve a specific feedback item

89
00:04:36,000 --> 00:04:38,000
from the feedback json file.

90
00:04:39,000 --> 00:04:43,000
For this, I still wanna get access to that file.

91
00:04:43,000 --> 00:04:46,000
So I will still import my two functions

92
00:04:46,000 --> 00:04:48,000
from that other file here.

93
00:04:48,000 --> 00:04:53,000
So from the feedback.js file, the buildFeedbackPath

94
00:04:53,000 --> 00:04:56,000
and the extractFeedback functions,

95
00:04:56,000 --> 00:04:58,000
again we could outsource them

96
00:04:58,000 --> 00:05:02,000
in some global helpers file if we wanted to.

97
00:05:02,000 --> 00:05:04,000
And then I'll construct my file path

98
00:05:04,000 --> 00:05:06,000
by calling buildFeedbackPath

99
00:05:06,000 --> 00:05:11,000
and get my feedbackData by calling extractFeedback

100
00:05:13,000 --> 00:05:17,000
and passing file path as an argument.

101
00:05:17,000 --> 00:05:20,000
Now, feedbackData is then an array of all items.

102
00:05:20,000 --> 00:05:21,000
And now here,

103
00:05:21,000 --> 00:05:25,000
I just want to get all the data for one specific item.

104
00:05:25,000 --> 00:05:27,000
So since this is an array,

105
00:05:27,000 --> 00:05:30,000
we can of course just call feedbackData.find

106
00:05:30,000 --> 00:05:32,000
to find one single item

107
00:05:33,000 --> 00:05:36,000
which then executes a function on every item

108
00:05:36,000 --> 00:05:37,000
to find out whether

109
00:05:37,000 --> 00:05:40,000
that is the item we're looking for or not.

110
00:05:40,000 --> 00:05:44,000
And the item we're looking for is the item where feedback.id

111
00:05:44,000 --> 00:05:47,000
is equal to feedbackId.

112
00:05:49,000 --> 00:05:51,000
So that is then the selectedFeedback.

113
00:05:52,000 --> 00:05:54,000
And that's the kind of data we now want

114
00:05:54,000 --> 00:05:58,000
to send back with that for incoming requests.

115
00:05:59,000 --> 00:06:02,000
And for this, we used the response object,

116
00:06:02,000 --> 00:06:06,000
set a status of 200 and set our json response body data

117
00:06:08,000 --> 00:06:10,000
which could carry an items key

118
00:06:10,000 --> 00:06:14,000
which is an object here where I set the feedback key,

119
00:06:14,000 --> 00:06:17,000
lets say, to selectedFeedback.

120
00:06:18,000 --> 00:06:22,000
And now that would return a feedback for a selected ID.

121
00:06:22,000 --> 00:06:24,000
Now, just to make that crystal clear,

122
00:06:24,000 --> 00:06:26,000
your dynamic API routes,

123
00:06:26,000 --> 00:06:29,000
cannot just handle get requests.

124
00:06:29,000 --> 00:06:32,000
Here, I'm not checking the request method at all

125
00:06:32,000 --> 00:06:34,000
which means that for all incoming requests,

126
00:06:34,000 --> 00:06:37,000
I'm just sending back this json data.

127
00:06:37,000 --> 00:06:40,000
But we could all check the request method here

128
00:06:40,000 --> 00:06:42,000
and do something different for post requests

129
00:06:42,000 --> 00:06:44,000
if we needed to.

130
00:06:44,000 --> 00:06:46,000
For example, you could check for delete requests.

131
00:06:46,000 --> 00:06:51,000
And if a delete request is sent for a specific feedback ID,

132
00:06:51,000 --> 00:06:54,000
you could execute some code that deletes

133
00:06:54,000 --> 00:06:57,000
that feedback from our stored feedback items.

134
00:06:57,000 --> 00:07:00,000
It's not a functionality I need here,

135
00:07:00,000 --> 00:07:02,000
but it is something you could also build.

136
00:07:02,000 --> 00:07:06,000
So dynamic routes work for all request methods,

137
00:07:06,000 --> 00:07:08,000
put, post, delete, get and so on

138
00:07:08,000 --> 00:07:12,000
and you can of course differentiate what you do

139
00:07:12,000 --> 00:07:15,000
inside of your handler function, with if checks.

140
00:07:16,000 --> 00:07:19,000
Here, I just wanna return my selected feedback no matter

141
00:07:19,000 --> 00:07:21,000
which method was used though

142
00:07:21,000 --> 00:07:24,000
and therefore that's the code we can use.

143
00:07:24,000 --> 00:07:26,000
Now we added this API route.

144
00:07:26,000 --> 00:07:29,000
Now we can use it in our feedback page.

145
00:07:29,000 --> 00:07:31,000
Here, when this button is clicked,

146
00:07:31,000 --> 00:07:34,000
I wanna send the request to this dynamic API route

147
00:07:34,000 --> 00:07:38,000
to fetch the details for a single feedback.

148
00:07:38,000 --> 00:07:40,000
And for this and the feedback page component,

149
00:07:40,000 --> 00:07:42,000
we can add a function,

150
00:07:42,000 --> 00:07:46,000
loadFeedbackHandler or whatever you wanna call it.

151
00:07:48,000 --> 00:07:50,000
And then in here, send the request.

152
00:07:50,000 --> 00:07:53,000
So now that's connect loadFeedbackHandler to this button

153
00:07:53,000 --> 00:07:57,000
and with onClick and in loadFeedbackHandler,

154
00:07:57,000 --> 00:08:01,000
we now need to know for which id to load the feedback.

155
00:08:01,000 --> 00:08:03,000
So we expect id as a parameter

156
00:08:03,000 --> 00:08:06,000
and to make sure that this id is passed in,

157
00:08:06,000 --> 00:08:08,000
when we bind our loadFeedbackHandler

158
00:08:08,000 --> 00:08:12,000
to the onClick prop, when we pass it into onClick,

159
00:08:12,000 --> 00:08:14,000
I'll call bind on that function,

160
00:08:14,000 --> 00:08:16,000
which is a built in JavaScript method

161
00:08:16,000 --> 00:08:21,000
to pre-configure this function for a future execution.

162
00:08:21,000 --> 00:08:23,000
If it's not clear how bind works,

163
00:08:23,000 --> 00:08:26,000
attached you'll find an additional resource on that,

164
00:08:26,000 --> 00:08:28,000
which clarifies it.

165
00:08:28,000 --> 00:08:32,000
Bind in the end allows us to pre-configure this function.

166
00:08:32,000 --> 00:08:34,000
So it does not execute the function yet,

167
00:08:34,000 --> 00:08:37,000
but it pre-configures it for future execution.

168
00:08:38,000 --> 00:08:43,000
And for example, allows us to pre-configure parameter values

169
00:08:43,000 --> 00:08:45,000
that will be received here.

170
00:08:45,000 --> 00:08:48,000
Now, the first value, the first argument we pass

171
00:08:48,000 --> 00:08:52,000
to bind is a value for the this keyword inside

172
00:08:52,000 --> 00:08:53,000
of this function.

173
00:08:53,000 --> 00:08:55,000
We don't care about that here,

174
00:08:55,000 --> 00:08:56,000
so we can set this to null.

175
00:08:56,000 --> 00:08:59,000
And then the second value we pass to bind,

176
00:08:59,000 --> 00:09:02,000
will be the value for the first argument,

177
00:09:02,000 --> 00:09:05,000
the first parameter received by that function.

178
00:09:05,000 --> 00:09:08,000
And here that should be item.id

179
00:09:08,000 --> 00:09:10,000
so that this button,

180
00:09:10,000 --> 00:09:13,000
when it's clicked or this function execution,

181
00:09:13,000 --> 00:09:16,000
uses the id of the item we're currently rendering.

182
00:09:16,000 --> 00:09:19,000
So that's then the value which we receive here.

183
00:09:19,000 --> 00:09:21,000
And then we can use the fetch function

184
00:09:21,000 --> 00:09:22,000
to again, send the request.

185
00:09:22,000 --> 00:09:26,000
Send the request to /api/

186
00:09:26,000 --> 00:09:27,000
and then the feedback id.

187
00:09:27,000 --> 00:09:30,000
So we add id to that path

188
00:09:31,000 --> 00:09:34,000
or we build that with the template literal notation,

189
00:09:34,000 --> 00:09:38,000
with back ticks and sent this to /api/

190
00:09:38,000 --> 00:09:41,000
and inject id like this.

191
00:09:41,000 --> 00:09:46,000
Either way, this produces a URL like /api/some-feedback-id

192
00:09:48,000 --> 00:09:51,000
and that will then trigger this dynamic route.

193
00:09:52,000 --> 00:09:54,000
Now we're still working with promises here.

194
00:09:54,000 --> 00:09:56,000
So we'll then still add a then block

195
00:09:56,000 --> 00:10:00,000
to get our response eventually and parse that data.

196
00:10:00,000 --> 00:10:03,000
We could also add error handling here,

197
00:10:03,000 --> 00:10:06,000
but I'll not do it here to keep this shorter.

198
00:10:06,000 --> 00:10:07,000
And then we got this data

199
00:10:07,000 --> 00:10:10,000
which we can use in this second, then block.

200
00:10:10,000 --> 00:10:12,000
Now here, we might want to render the details.

201
00:10:12,000 --> 00:10:14,000
So again, we can use useState

202
00:10:14,000 --> 00:10:17,000
for this to update our component

203
00:10:17,000 --> 00:10:20,000
and what's rendered once we got the data.

204
00:10:20,000 --> 00:10:24,000
So from react, I'll import useState here

205
00:10:25,000 --> 00:10:28,000
and then set up some state for this component.

206
00:10:29,000 --> 00:10:34,000
The feedbackData, let's say with the setFeedbackData,

207
00:10:34,000 --> 00:10:38,000
state updating function, where we call useState.

208
00:10:38,000 --> 00:10:40,000
And initially that's undefined.

209
00:10:40,000 --> 00:10:44,000
We have no starting value, but in this then block,

210
00:10:44,000 --> 00:10:47,000
once we have the data fetched from our API,

211
00:10:47,000 --> 00:10:52,000
we can call setFeedbackData to set data.feedback,

212
00:10:54,000 --> 00:10:56,000
like this as our new state.

213
00:10:56,000 --> 00:11:01,000
Now data.feedback, because in this dynamic API route,

214
00:11:01,000 --> 00:11:05,000
I'm setting a feedback property in that response object.

215
00:11:05,000 --> 00:11:09,000
So that is the property holding the selected feedback data.

216
00:11:09,000 --> 00:11:12,000
So that full feedback object fetched

217
00:11:12,000 --> 00:11:13,000
from feedback json.

218
00:11:13,000 --> 00:11:17,000
And therefore it's this property named feedback

219
00:11:17,000 --> 00:11:20,000
which I wanna access here in my front end code

220
00:11:20,000 --> 00:11:23,000
as well as my feedback data.

221
00:11:23,000 --> 00:11:27,000
That is standard object fetched from feedback json,

222
00:11:27,000 --> 00:11:30,000
which I set as my feedback data here.

223
00:11:30,000 --> 00:11:33,000
Now, when that's called, the component will be re-evaluated,

224
00:11:33,000 --> 00:11:35,000
because the state changed.

225
00:11:35,000 --> 00:11:36,000
And we can utilize this

226
00:11:36,000 --> 00:11:40,000
to output the email address for this feedback.

227
00:11:40,000 --> 00:11:42,000
So when that button was clicked,

228
00:11:42,000 --> 00:11:44,000
we now wanna show the email address.

229
00:11:44,000 --> 00:11:46,000
And since I always just have feedback data

230
00:11:46,000 --> 00:11:49,000
for one specific feedback loaded,

231
00:11:49,000 --> 00:11:51,000
the way my component is designed here,

232
00:11:51,000 --> 00:11:53,000
I'll do this above the unordered list.

233
00:11:53,000 --> 00:11:56,000
Use fragment, import it from react,

234
00:11:56,000 --> 00:11:59,000
because adjacent JSX code isn't allowed,

235
00:11:59,000 --> 00:12:02,000
otherwise move that in here.

236
00:12:02,000 --> 00:12:05,000
And then here, render something conditionally.

237
00:12:05,000 --> 00:12:07,000
If feedbackData is set,

238
00:12:07,000 --> 00:12:12,000
then I wanna output, let's say a paragraph

239
00:12:12,000 --> 00:12:15,000
where I just output feedbackData.email.

240
00:12:16,000 --> 00:12:20,000
The .email because feedbackData will be a single piece

241
00:12:20,000 --> 00:12:23,000
of data from feedback json, so such an object.

242
00:12:23,000 --> 00:12:26,000
And in those objects, we do have an email property.

243
00:12:26,000 --> 00:12:27,000
So we can access that here.

244
00:12:27,000 --> 00:12:31,000
And then we'll show up the data for the loaded feedback

245
00:12:31,000 --> 00:12:35,000
for a single piece of feedback above the list of feedbacks.

246
00:12:35,000 --> 00:12:35,000
Now that is of course,

247
00:12:35,000 --> 00:12:39,000
all just some very basic unstyled dummy code

248
00:12:39,000 --> 00:12:43,000
to show you how you can interact with those API routes.

249
00:12:45,000 --> 00:12:48,000
Hence if you now save everything and reload /feedback,

250
00:12:48,000 --> 00:12:51,000
we do have to show details button.

251
00:12:51,000 --> 00:12:54,000
And if we click it, we see eventually the email address

252
00:12:54,000 --> 00:12:57,000
of that feedback shows up at the top.

253
00:12:57,000 --> 00:12:59,000
Now, as I mentioned before,

254
00:12:59,000 --> 00:13:02,000
this is kind of redundant, because with getStaticProps,

255
00:13:02,000 --> 00:13:06,000
we already fetched the full feedback data.

256
00:13:06,000 --> 00:13:09,000
So we have all that data exposed through props

257
00:13:09,000 --> 00:13:11,000
in that component already.

258
00:13:11,000 --> 00:13:13,000
So sending another request for a single piece

259
00:13:13,000 --> 00:13:17,000
of data here is redundant, but of course it's not redundant

260
00:13:17,000 --> 00:13:21,000
for you to know about this dynamic API route feature

261
00:13:21,000 --> 00:13:25,000
which is why I used this example for showing this to you.

262
00:13:25,000 --> 00:13:28,000
Because this is how you can send requests

263
00:13:28,000 --> 00:13:30,000
to dynamic API routes

264
00:13:30,000 --> 00:13:33,000
and how you can set up dynamic API routes

265
00:13:33,000 --> 00:13:35,000
to execute service side code

266
00:13:35,000 --> 00:13:39,000
for dynamic pieces of data encoded in the path.

