Symfony RESTful API: Hypermedia, Links & Bonuses (Course 5)

After 4 courses, we've somehow avoided the hottest buzzwords in REST: Hypermedia and HATEOAS. These can make your API awesome, or could bring you to your knees with fuzzy details, missing best practices and complexity. Let's make our API awesome:

  • Linking to Resources (and Hypermedia) without hating it
  • Controlling your JSON fields with VirtualProperty and SerializedName
  • Customizing your input field names with property_path
  • The wonderful HATEOAS php library
  • HAL+JSON... and whether you want to use it or not
  • Subordinate resources!
  • Handle ugly, non-RESTful, weird endpoints with some swagger

Your Guides

Ryan Weaver Leanna Pelham

Questions? Conversation?

  • 2016-08-23 weaverryan

    I like it!

    I've just updated the starting code to add the static::fail() line :) (ref https://github.com/knpuniversi.... I kept the stopOnError stuff the way it was - I don't feel too strongly about those settings, and the user can override them.

    Thanks for the suggestion!

  • 2016-08-20 Vlad

    How about this:


    $baseUrl = getenv('TEST_BASE_URL');
    if (!$baseUrl) {
    static::fail('No TEST_BASE_URL environmental variable set in phpunit.xml.');
    }

    I've also added:


    stopOnError="true"
    stopOnFailure="true"

    to the phpunit.xml file

  • 2016-08-19 weaverryan

    Hi Vlad!

    Yes, you caught me - I saw this recently :). I actually don't remember what I was thinking here. In fact, my only idea was that I was thinking about doing a (!$baseUrl), and then throwing an exception to help the user know this isn't set. I'm not sure if that's what I was thinking... but it's either that or nothing: I haven't seen any bug or problem with the code that I now realized I forgot to fix.

    Unless you can see something I may have meant? That would be awesome :).

    Cheers!

  • 2016-08-19 Vlad

    Hi Ryan,
    In ApiTestCase::setUpBeforeClass there is an empty if statement:


    public static function setUpBeforeClass()
    {
    $handler = HandlerStack::create();

    $handler->push(Middleware::history(self::$history));
    $handler->push(Middleware::mapRequest(function(RequestInterface $request) {
    $path = $request->getUri()->getPath();
    if (strpos($path, '/app_test.php') !== 0) {
    $path = '/app_test.php' . $path;
    }
    $uri = $request->getUri()->withPath($path);

    return $request->withUri($uri);
    }));

    $baseUrl = getenv('TEST_BASE_URL');
    if ($baseUrl) {

    }
    self::$staticClient = new Client([
    'base_uri' => $baseUrl,
    'http_errors' => false,
    'handler' => $handler
    ]);

    self::bootKernel();
    }

    specifically:


    if ($baseUrl) {

    }

    What should go there?
    Thanks!

  • 2016-08-13 Thierno Diop

    Thx u so much its very clear now
    cheers

  • 2016-08-12 weaverryan

    Hey Thierno!

    I don't think you need to worry about performance - that's just a big topic, and one you can worry about later (neither method is inherently faster/slower). I typically recommend doing whatever you're more familiar with if you need to build this for a client or have some budget/deadline. But if this is more of a personal project and you want to learn, go with the approach that's less familiar to you :).

    Good luck!

  • 2016-08-11 Thierno Diop

    Thx you Ryan for your answer.
    I see what you mean but i want to make a social network in a single page app with angular 2 in the front-end and an API in the back-end with symfony 3 but i dont know if it is a good solution to develop it in a single page however it would be really cool if i could do this without leak of performance because i dont know if there is a problem with SPA and classic site in term of performance !!
    THX

  • 2016-08-11 weaverryan

    Hey Thierno!

    Ha, that's a big question! :) Maybe you can tell me what things specifically are the most confusing, and we can try to clear those up! We're planning on a ReactJS + Symfony tutorial soon (maybe also Angular after) - but if you have some specific questions, let me know!

    Part of the problem is that there are many ways to do things. You might have a pure JS frontend and a pure API backend. In this case, I would still keep them in the same git repository (for convenience), but they would be isolated. Then, you need to decide how you want to handle authentication. Btw, in some pure JS frontends, people actually just have one index.html file that holds the JS code to bootstrap things. If your app is this pure, you can even deploy this file (and of course your JS files) to a CDN for faster performance.

    Or, you might have a mix of a traditional web app with some pages that host reach Angular/React applications. We do exactly that on KnpU. This is a bit easier, as we just rely on our cookie/session authentication when making AJAX calls that require authentication.

    Cheers!

  • 2016-08-10 Thierno Diop

    Hello Ryan,
    What is the best way to do a single page with angular 2 and symfony 3 ?
    I mean the architecture and also the deployement
    Please with details because i am so confused THX!!! You are doing an awesome job here keep going !!!!!

  • 2016-07-07 weaverryan

    Hey Vlad!

    When it comes to files, I think the best answer is to do whatever you would normally do on the web - i.e. return the same data (so in this case, probably binary) and content-type as normal. Also, if you look at GitHub's API (they're my goto to look at, because it's used by many people and is actually quite nice to use), if you ever ask them for a "download", they return JSON, with a key on that JSON to the URL the client can use to go fetch that assets. Then, I assume, they just serve that asset from a CDN. But, returning the PDF directly from a controller is also fine.

    Cheers!

  • 2016-07-06 Vlad

    Hi Ryan,
    What is the proper way to send images and PDF files in a REST API? Should it be sent as a base64-encoded string, or as binary?
    Thanks,

  • 2016-05-18 weaverryan

    This week! Wed or Thu actually. So nice timing :D

  • 2016-05-17 TheLastTamurai

    Any news here?!
    ;)

  • 2016-04-29 Neandher Carlos

    Understand. That is made in Symfony: https://api-platform.com. I keep an eye on it too.

  • 2016-04-29 weaverryan

    I think it's a good idea. In my limited experience, it's crazy verbose - I don't love how Zend usually does things, but I keep an eye on it :).

  • 2016-04-28 Neandher Carlos

    About episode 6, my vote is: YEEEEES!!!!! - Sorry, Brazil crazy things!
    What do you think about: https://apigility.org
    :)

  • 2016-04-13 weaverryan

    Not in this one, but I LOVE that bundle. I *am* considering an episode 6 about documentation - basically moving the planned ep3 from the Silex rest series over here as ep 6.

    I've already finished recording this course, and I'm *really* excited about it - watch for it in a few weeks!

  • 2016-04-07 Neandher Carlos

    You will talk about NelmioApiDocBundle in this course?