API Platform Part 3- Custom Resources.pdf
(
1342 KB
)
Pobierz
API Platform Part 3: Custom
Resources
With <3 from SymfonyCasts
Chapter 1: App & Test Setup
Hey friends. Yea! It's time for part 3 of our API Platform tutorial series. First, let's do a status check, because we have been
busy!
In
part 1,
we got everything we needed for a pretty sweet API. We talked about JSON-LD and OpenAPI, operations and
config, serialization groups, validation, relations, IRIs, filtering and more.
In
part 2,
we talked about security, logging in, adding authorization checks to operations, making it so that
certain
fields can
be read or written only by
specific
users and some pretty serious work related to custom normalizers for even more control
over
exactly
which fields each user sees.
So what's in part 3? It's time to take customizations to the next level, like making it possible to publish an item and run code
when that happens... kind of like a custom "publish" operation... but with a RESTful twist. We'll also add complex security
rules around who can publish an item under different conditions. Then we'll do everything custom: add completely custom
fields, completely custom API resources that aren't backed by Doctrine, custom filters and we'll even dive deep into API
Platform's input and output DTO system. Whoa.
To be honest, this was
not
an easy tutorial to write. Not because it was hard to figure out how to make these customizations -
though, some of this
is
tricky - but because we're getting
so
deep into API Platform, that sometimes there are
multiple
ways to
accomplish something. We'll find the best paths and learn why. Oh, and a huge thanks to
Kévin Dunglas
and
Antoine
Bluchet
- core API platform developers - who helped me a
ton
to find those best paths.
Project Setup
So... let's go! To POST the most new data to your brain, you should
totally
code along with me! Download the course code
from this page and, after unzipping it, you'll find a start/ directory with the same code that you see here. Pop open up the
README.md file for all the details about getting this project working on your machine.
Now, it's
optional,
but, for this tutorial, I'm using a special Docker and symfony binary integration to spin up and configure my
database. The details are in the README and you can learn more about it in our
Symfony Doctrine Tutorial.
Anyways, one of the steps in the README is to find a terminal, move into the project and run:
symfony serve -d
to start a dev web server at https://127.0.0.1:8000. Copy that URL, find your browser and say hello to... CheeseWhiz! Our
peer-to-peer cheese selling site where the world can find - and purchase - the cheesy treasures that you forgot were in your
fridge.
Our site
does
have a tiny frontend - this is build in Vue.js - but mostly it's just for logging in. The vast majority of the site is an
API. Go to /api to see the interactive documentation generated by Swagger.
Updates since Episode 2
Now, if you coded along with me in episodes one and two, first: you rock, and second, this
is
the same app, but with some
changes... so make sure to download the latest code. First, we upgraded our dependencies to use Symfony 5.1 and API
platform 2.5:
79 lines
composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 7
"api-platform/core":
"^2.1",
... lines 9 - 16
"symfony/asset":
"5.1.*",
"symfony/console":
"5.1.*",
"symfony/dotenv":
"5.1.*",
"symfony/expression-language":
"5.1.*",
"symfony/flex":
"^1.1",
"symfony/framework-bundle":
"5.1.*",
"symfony/http-client":
"5.1.*",
"symfony/monolog-bundle":
"^3.4",
"symfony/security-bundle":
"5.1.*",
"symfony/twig-bundle":
"5.1.*",
"symfony/validator":
"5.1.*",
"symfony/webpack-encore-bundle":
"^1.6",
"symfony/yaml":
"5.1.*",
... line 30
},
... lines 32 - 71
"extra": {
"symfony": {
... line 74
"require":
"5.1.*"
}
}
}
I also added
Foundry
to our system, which is a new library that makes it
really
easy to create dummy data:
79 lines
composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 29
"zenstruck/foundry":
"^1.1"
},
... lines 32 - 77
}
We're using Foundry inside of our data fixtures - so src/DataFixtures/AppFixtures.php - as a quick way to create a bunch of
users and cheese listings:
52 lines
src/DataFixtures/AppFixtures.php
... lines 1 - 12
class
AppFixtures
extends
Fixture
{
... lines 15 - 21
public function
load(ObjectManager
$manager)
{
$user = UserFactory::new()->create([
'email'
=>
'cheesefan@example.com',
'username'
=>
'cheesefan',
'password'
=>
$this->passwordEncoder->encodePassword(new
User(),
'cheese'),
]);
UserFactory::new()->createMany(50);
$listingFactory = CheeseListingFactory::new([
'owner'
=> $user,
])
->published();
$listingFactory->create([
'title'
=>
'Mysterious munster',
'description'
=>
'Origin date: unknown. Actual origin... also unknown.',
'price'
=>
1500,
]);
$listingFactory->create([
'title'
=>
'Block of cheddar the size of your face!',
'description'
=>
'When I drive it to your house, it will sit in the passenger seat of my car.',
'price'
=>
5000,
]);
// then create 30 more
$listingFactory->createMany(50);
}
}
We also use this inside our test suite. You don't need to know too much about Foundry, but if you're interested, check out our
Symfony Doctrine tutorial
for more details.
Running the Tests
Now, before we start, we
already
have a test suite in our project with some basic functional tests for our 2 API resources:
CheeseListing:
122 lines
tests/Functional/CheeseListingResourceTest.php
... lines 1 - 9
class
CheeseListingResourceTest
extends
CustomApiTestCase
{
public function
testCreateCheeseListing()
{
... lines 14 - 43
}
public function
testUpdateCheeseListing()
{
... lines 48 - 67
}
public function
testGetCheeseListingCollection()
{
... lines 72 - 102
}
public function
testGetCheeseListingItem()
{
... lines 107 - 119
}
}
and User:
75 lines
tests/Functional/UserResourceTest.php
... lines 1 - 8
class
UserResourceTest
extends
CustomApiTestCase
{
public function
testCreateUser()
{
... lines 13 - 24
}
public function
testUpdateUser()
{
... lines 29 - 45
}
public function
testGetUser()
{
... lines 50 - 72
}
}
We're going to rely on tests a
lot
in this tutorial... in part because, as cool as this interactive documentation is - and we
will
use it - it gets a bit tedious to
constantly
fill out the boxes to test manually. And, of course, having tests will guarantee our API
doesn't break.
So before we
start
breaking things on purpose, let's make sure the tests pass. At your terminal, run:
symfony run bin/phpunit
Tip
Using symfony php bin/phpunit is even better because it can intelligently find your PHP executable.
First, symfony run is just a shortcut to execute PHP. So this mean:
Plik z chomika:
sabat24
Inne pliki z tego folderu:
001-setup.mp4
(45902 KB)
002-persister-decoration.mp4
(51509 KB)
003-decoration-deep-dive.mp4
(44171 KB)
004-persister-context.mp4
(24230 KB)
005-setting-published.mp4
(43142 KB)
Inne foldery tego chomika:
Zgłoś jeśli
naruszono regulamin