Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This course is archived!
This tutorial uses a deprecated micro-framework called Silex. The fundamentals of REST are still ? valid, but the code we use can't be used in a real application.

The REST API Tutorial

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

The REST API Tutorial

Well hey there! I hope you’re ready to work, because we’re going to build an API from the ground up! It’s not going to be easy: there’s a lot to do and a lot of theory to sort through. But I promise you that you’ll be happy you made the effort.

We’ll of course use best practices and learn all about the theory behind REST. But we’re also going to be pragmatic. If you stick to the rules too much, you’ll get buried in technical draft specifications and blog post. You’ll also get the feeling that a perfectly RESTful API might be impossible, and it would probably be pretty tough to use anyways.

Instead, we’ll build a really nice API, keep to the best parts of REST, tell you when we’re breaking the rules and when the rules are still being debated. And we’re not going to stick to the easy stuff. Nope, we’ll attack the ugliest areas of an API, like custom methods and where each piece of documentation should live and why.

Leave a comment!

Login or Register to join the conversation
Yangzhi Avatar
Yangzhi Avatar Yangzhi | posted 11 days ago | edited

hi,i learn how to user processor state,but i have one question,for example,i use post to register user.normal will return user entity object. but i use jwt,so when user register,i want return jwt token,mean i want return string.but i got error:

"hydra:description": "ApiPlatform\Symfony\EventListener\WriteListener::getObjectClass(): Argument #1 ($object) must be of type object, string given, called in \/var\/www\/fast\/vendor\/api-platform\/core\/src\/Symfony\/EventListener\/WriteListener.php on line 111",

I kown use custom controller, please tell me is have other best way? thanks


Hi @Yangzhi!

On a technical level, when someone does a POST to create a new user, you are "supposed" to return the User resource in the JSON response. But... you can really do whatever you want :P. And you ALMOST have the solution. You must return an object from your processor. So, you could:

A) Create a new class called something like UserJwt with a token property on it
B) Create and return this from your processor

$userJwt = new UserJwt();
$userJwt->token = 'something';

return $userJwt;

So you have the correct idea, but what you return must be an object, which will then be sent through the serializer. If you want the documentation on your endpoint to be correct, you could even set the output: UserJwt::class for that operation.


Yangzhi Avatar
Yangzhi Avatar Yangzhi | weaverryan | posted 6 days ago | edited

so,i created src/Entity/CommonOutput.php, this is only one prop call private mixed $data = null;
in my src/Entity/Company.php,i write:
new Pst(uriTemplate: '/companies/login',output: CommonOutput::class,name:'company.login')
in processor file:

if ($operation->getName() === 'company.login') {
        $token = $this->tokenManager->create($user);
        $output = new CommonOutput();
        return $output;

i got: hydra:description
"Unable to generate an IRI for the item of type \"App\Entity\Company\""

Yangzhi Avatar
Yangzhi Avatar Yangzhi | posted 1 month ago | edited

Hi, some times, i must custom GetCollection operation by own uriTemplate and controller. on own controller my list like this:

public function __invoke(){
      return $this->json([
            'hydra:member' => $list,
            'hydra:totalItems' => $total
        ], context: ['groups' => 'list']);

then the each list object not return '@id'. please do hou have the best way? thanks


Hey @Yangzhi

This happens because you are returning a response object with everything serialized with default Symfony serializer, try to return a collection of objects $list variable

BTW https://api-platform.com/docs/core/pagination/#custom-controller-action here you can check ApiPlatform example on custom collection with pagination


1 Reply
Dylan J. Avatar
Dylan J. Avatar Dylan J. | posted 2 years ago

When setting up the code (creating the composer auto loader file) the code works fine, there is a little bit of styling issues, but my main issue is that i cannot choose an avatar therefor i am unable to actually get any further within the program, i've tried to do composer update, after it updates the program is unusable, anyone got any clue?


Hey @Dylan!

Yea, the REST fundamentals behind this course are still solid, but the code is OLD. So if you've got styling problems or you can't see the images, my guess is that there may be some minor misconfiguration with your server - all the CSS and images are normal, boring files that sit in the document root (the web directory).

If you open your browser's network tools and refresh, my guess is that you will see errors for the CSS file and image files. Try opening some of those URLs directly in your browser to see what the error is. Is it a 404? An access denied? Something else? And what are the URLs to the assets?

The good news is, I don't think this is a problem with outdated dependencies :).


Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses a deprecated micro-framework called Silex. The fundamentals of REST are still ? valid, but the code we use can't be used in a real application.

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "silex/silex": "~1.0", // v1.3.2
        "symfony/twig-bridge": "~2.1", // v2.7.3
        "symfony/security": "~2.4", // v2.7.3
        "doctrine/dbal": "^2.5.4", // v2.5.4
        "monolog/monolog": "~1.7.0", // 1.7.0
        "symfony/validator": "~2.4", // v2.7.3
        "symfony/expression-language": "~2.4" // v2.7.3
    "require-dev": {
        "behat/mink": "~1.5", // v1.5.0
        "behat/mink-goutte-driver": "~1.0.9", // v1.0.9
        "behat/mink-selenium2-driver": "~1.1.1", // v1.1.1
        "behat/behat": "~2.5", // v2.5.5
        "behat/mink-extension": "~1.2.0", // v1.2.0
        "phpunit/phpunit": "~5.7.0", // 5.7.27
        "guzzle/guzzle": "~3.7" // v3.9.3