So far we've been creating pages in our application, but
SvelteKit allows you to create more than just pages.
You can also create API routes by adding a server.js file instead of
a page server.js file in a page.svelte that exports functions corresponding
to HTTP methods like GET, POST, PATCH, PUT, DELETE, and so on.
So this app here fetches data from a /roll API route when you click the button.
And at the moment, we haven't implemented that route.
So let's do that by adding a src/routes/roll/+server.js file.
So click the new file icon, roll/server.js.
And from here, we can export functions that correspond to the HTTP Verbs.
In this case, we're gonna have a GET.
We'll get a random number between 1 and 6.
And we're gonna return that as a response object.
We need to add a header, That tells the browser
that the response is of type application/json.
Now just like request, this response thing here is a is a web standard.
It's an object that you deal with when you use the Fetch API, and other times..
And so inside our API route handlers, our job is to take your request and
return one of these response objects.
And you'll find the documentation on MDM.
Now since doing this sort of thing is pretty common in an API route,
returning json, we actually have a helper to do that for you.
I'm gonna import that helper now, import {json} from 'sveltejs/kit'.
And then instead of returning all of this,
we're just gonna return json and then pass in the data.
So now, if we roll the dice, we're gonna fetch the response,
which is the same response object that we've just returned from the API route.
And we're gonna assign that to this local value that gets shown when we've rolled.
Rolled a 1, not very good, try again, rolled a 4.
I'm gonna keep going until I get a 6.
Come on.
Is my logic bad?
I got a six, finally.
All right, we can move on to the next section.
Okay, so that was a GET handler, but you can also add handlers that mutate data,
such as a POST handler.
Now, in most cases,
you shouldn't use a POST handler when you could use a form action instead.
Form actions that are gonna involve less code for you to write.
And they also work without JavaScript as we've seen, making things more resilient.
But we can do it if we need to for some reason.
So we're gonna revisit the todo app from default and
we're gonna implement it this time using an API route.
Site the key down event handler of the input at the top here,
we're gonna post some data to the server.
Response is gonna be the result of fetching the todo API route.
Is gonna be a POST call, so add method post.
The body is gonna be a stringified JSON
object containing the description.
And we're gonna add that content type-application, json header.
Okay, so when we hit the Enter key inside this todo,
we're posting data to a route that we haven't yet created.
So we need to create that now.
Inside the routes directory, create a todo folder, then inside there,
create our server.js.
This time, we're gonna define a POST handler instead of a GET handler.
Gonna import that json helper cuz we're gonna use it in a minute.
And we're gonna import the same database object that we were
using inside the form action before, import * as database from
'$lib/server/database.js', that's this file over here.
Got a question from the crowd?
>> Are API endpoints open by default?
Or do you need some sort of codes config to open up for third party users?
>> Yes, so that's a very good question.
SvelteKit will by default lock down your API routes to
prevent people from posting data from different sites.
So to protect your users from phishing attacks and things like that.
Where someone has a website that looks like yours and posts some malicious data,
which then uses your cookies to do something nefarious,
SvelteKit will will look at the origin header when a request comes in.
And if you're trying to mutate some data, it will reject it by default.
You can disable that behavior and you can add your own caused behavior if you want,
but the default behavior is to try and keep your users safe.
Hopefully, that answers the question?
>> Is that JSON utility just using JSON.parse under the hood or
does it support like begins?
>> It's just stringifying the data that you pass in.
Yeah, it's basically just sugar over returning a new response with
JSON.stringify, the same data.
Yeah, if you wanna pass rich data, then you're gonna need to use your own
serialization and your own deserialization on the client.
All right, so we've imported everything that we need.
It's time to add the handler itself.
First thing we'll do is get the JSON that was sent
from the browser using await request.json.
We're gonna grab the userid from the cookies,
And then we're gonna get the ID of the todo that we create so
that we can pass it back.
Passing the userid and the description.
Right, and that's gonna call the createTodo function here.
Which is gonna create a new id, just a random string of digits.
It'll add that to the in-memory database and
then it'll return the id to whatever called it.
Then we can take that ID send it back to the browser.
We're gonna pass in status 201.
This time, 201 is the HTTP status code that you use when you create a resource.
If you wanna learn more about HTTP status codes which we'll use a few times in this
workshop, there's a site which is very helpful.
Explains the difference between, for example, an HTTP 200 and a 201.
No, look, there we go, 200, okay?
So back inside the event handler on the page,
we need to do something with the response that was just generated.
Grab the response json,
In much the same way that we got the request json on the server.
And then, we're gonna mutate the todo array directly inside this handler.
And then finally, the value gets reset so that we can add a new todo.
Now this mutation that we're doing here, this is perhaps a little bit unorthodox.
You should only do this if the result of that mutation is the same result that
you get if you reload the page, otherwise, you will get into an inconsistent state.
But because we control this state, it's a safe mutation to make.
So now if I add to do, It's gonna add that to the list.