WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:01.066 --> 00:00:06.036 align:middle
In a future tutorial, we're going to
create a database to manage songs, genres,

00:00:06.036 --> 00:00:09.436 align:middle
and the mixed vinyl records
that our users are creating.

00:00:10.266 --> 00:00:13.556 align:middle
Right now, we're working
entirely with hardcoded data...

00:00:13.976 --> 00:00:18.236 align:middle
but our controllers - and -
especially templates won't feel

00:00:18.236 --> 00:00:20.896 align:middle
that much different once
we make this all dynamic.

00:00:21.596 --> 00:00:26.066 align:middle
So here's our new goal: I
want to create an API endpoint

00:00:26.066 --> 00:00:29.876 align:middle
that will return the data
for a single song as JSON.

00:00:30.606 --> 00:00:35.576 align:middle
We're going to use this in a few minutes
to bring this play button to life.

00:00:35.696 --> 00:00:40.136 align:middle
At the moment, none of these buttons
do anything, but they do look pretty.

00:00:41.016 --> 00:00:44.306 align:middle
The two steps to creating an API endpoint are...

00:00:44.656 --> 00:00:49.906 align:middle
exactly the same as creating an HTML
page: we need a route and a controller.

00:00:49.906 --> 00:00:57.076 align:middle
Since this API endpoint will be returning song
data, instead of adding another method inside

00:00:57.076 --> 00:01:01.056 align:middle
of VinylController, let's create
a totally new controller class.

00:01:01.736 --> 00:01:05.006 align:middle
How you organize this stuff
is entirely up to you.

00:01:05.726 --> 00:01:08.156 align:middle
Create a new PHP class called SongController...

00:01:08.446 --> 00:01:11.736 align:middle
or SongApiController would also be a good name.

00:01:12.486 --> 00:01:17.846 align:middle
Inside, this will start like any other
controller, by extending AbstractController.

00:01:18.556 --> 00:01:20.476 align:middle
Remember: that's optional...

00:01:20.566 --> 00:01:23.576 align:middle
but it gives us shortcut
methods with no downside.

00:01:23.576 --> 00:01:28.216 align:middle
Next, create a public function
called, how about, getSong().

00:01:30.346 --> 00:01:31.826 align:middle
Add the route...

00:01:31.826 --> 00:01:37.586 align:middle
and hit tab to auto-complete this so that
PhpStorm adds the use statement on top.

00:01:38.546 --> 00:01:49.286 align:middle
Set the URL to /api/songs/{id}, where id will
eventually be the database id of the song.

00:01:50.106 --> 00:01:56.316 align:middle
And because we have a wildcard in the route,
we are allowed to have an $id argument.

00:01:56.406 --> 00:02:00.226 align:middle
Finally, even though we don't need to do this,

00:02:00.456 --> 00:02:04.646 align:middle
because we know that our controller
will return a Response object,

00:02:04.906 --> 00:02:07.266 align:middle
we can set that as the return type.

00:02:07.796 --> 00:02:13.086 align:middle
Make sure to auto-complete the one from
Symfony's HttpFoundation component.

00:02:14.286 --> 00:02:18.086 align:middle
Inside the method, to start, dd($id)...

00:02:18.656 --> 00:02:20.626 align:middle
just to see if everything is working.

00:02:21.616 --> 00:02:22.426 align:middle
Let's do this!

00:02:23.116 --> 00:02:28.186 align:middle
Head over to /api/songs/5 and...

00:02:28.496 --> 00:02:31.406 align:middle
got it! Another new page.

00:02:32.276 --> 00:02:37.666 align:middle
Back in that controller, I'm going to
paste in some song data: eventually,

00:02:37.666 --> 00:02:39.906 align:middle
this will come from the database.

00:02:40.386 --> 00:02:43.056 align:middle
You can copy this from the
code block on this page.

00:02:43.796 --> 00:02:46.806 align:middle
Our job is to return this as JSON.

00:02:47.466 --> 00:02:51.356 align:middle
So how do we return JSON in Symfony?

00:02:51.356 --> 00:02:56.156 align:middle
By returning a new JsonResponse
and passing it the data.

00:02:56.156 --> 00:02:58.846 align:middle
I know... too easy!

00:02:58.846 --> 00:03:01.066 align:middle
Refresh and...

00:03:01.336 --> 00:03:03.026 align:middle
hello JSON!

00:03:03.886 --> 00:03:06.506 align:middle
Now you might be thinking: Ryan!

00:03:06.676 --> 00:03:09.556 align:middle
You've been telling us - repeatedly -

00:03:09.816 --> 00:03:13.846 align:middle
that a controller must all always
return a Symfony Response object,

00:03:14.136 --> 00:03:16.196 align:middle
which is what render() returns.

00:03:16.766 --> 00:03:20.226 align:middle
Now you're returning some
other type of Response object?

00:03:20.766 --> 00:03:21.836 align:middle
Ok, fair...

00:03:22.326 --> 00:03:25.986 align:middle
but this works because JsonResponse
is a Response.

00:03:26.416 --> 00:03:27.306 align:middle
Let me explain.

00:03:27.776 --> 00:03:32.616 align:middle
Sometimes it's useful to jump into
core classes to see how they work.

00:03:33.376 --> 00:03:38.736 align:middle
To do that, in PHPStorm - if you're on a
Mac hold command, otherwise hold control -

00:03:38.916 --> 00:03:42.006 align:middle
and then click the class name
that you want to jump into.

00:03:42.566 --> 00:03:44.596 align:middle
And... surprise!

00:03:44.846 --> 00:03:48.976 align:middle
JsonResponse extends Response.

00:03:49.086 --> 00:03:52.086 align:middle
Yea, we're still returning a Response.

00:03:52.506 --> 00:03:57.636 align:middle
But this sub-class is nice because it
automatically JSON encodes our data

00:03:57.976 --> 00:04:02.366 align:middle
and sets the Content-Type
header to application/json.

00:04:03.296 --> 00:04:10.796 align:middle
Oh, and back in our controller, we can be even
lazier by saying return $this-&gt;json($song)...

00:04:11.436 --> 00:04:16.846 align:middle
where json() is another shortcut method
that comes from AbstractController.

00:04:17.696 --> 00:04:23.886 align:middle
Doing this makes absolutely no difference
because this is just a shortcut to return ...

00:04:24.036 --> 00:04:25.616 align:middle
a JsonResponse!

00:04:26.186 --> 00:04:32.576 align:middle
If you're building a serious API, Symfony
has a serializer component that's really good

00:04:32.576 --> 00:04:34.676 align:middle
at turning objects into JSON...

00:04:34.756 --> 00:04:37.476 align:middle
and then JSON back into objects.

00:04:38.186 --> 00:04:41.386 align:middle
We talk a lot about it in
our API Platform tutorial,

00:04:41.646 --> 00:04:46.946 align:middle
which is a powerful library
for creating APIs in Symfony.

00:04:47.036 --> 00:04:50.296 align:middle
Next, let's learn how to
make our routes smarter,

00:04:50.646 --> 00:04:56.756 align:middle
like by making a wildcard only match a
number, instead of matching anything.

