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.

PUT: Killing Duplicated Code

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

PUT: Killing Duplicated Code

Our tests are passing, but we’re doing a bad job: I’ve created duplicated code in newAction and updateAction!

Let’s redeem ourselves! Create a new private function called handleRequest and copy the code into it that reads the request body and sets the data on the Programmer:

// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...

private function handleRequest(Request $request, Programmer $programmer)
{
    $data = json_decode($request->getContent(), true);

    $programmer->nickname = $data['nickname'];
    $programmer->avatarNumber = $data['avatarNumber'];
    $programmer->tagLine = $data['tagLine'];
    $programmer->userId = $this->findUserByUsername('weaverryan')->id;
}

Cool! Now we can just call this from newAction and updateAction:

// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...

public function newAction(Request $request)
{
    $programmer = new Programmer();
    $this->handleRequest($request, $programmer);
    $this->save($programmer);

    // ...
}

public function updateAction($nickname, Request $request)
{
    $programmer = $this->getProgrammerRepository()->findOneByNickname($nickname);

    if (!$programmer) {
        $this->throw404();
    }

    $this->handleRequest($request, $programmer);
    $this->save($programmer);

    // ...
}

Re-run the tests to see if we broke anything:

$ php vendor/bin/behat

Cool! I’m going to change how this code is written just a little bit so that it’s even more dynamic:

// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...

private function handleRequest(Request $request, Programmer $programmer)
{
    $data = json_decode($request->getContent(), true);

    if ($data === null) {
        throw new \Exception(sprintf('Invalid JSON: '.$request->getContent()));
    }

    // determine which properties should be changeable on this request
    $apiProperties = array('nickname', 'avatarNumber', 'tagLine');

    // update the properties
    foreach ($apiProperties as $property) {
        $val = isset($data[$property]) ? $data[$property] : null;
        $programmer->$property = $val;
    }

    $programmer->userId = $this->findUserByUsername('weaverryan')->id;
}

There’s nothing important in this change, but it’ll make some future changes easier to understand. If you’re using a form library or have a fancier ORM, you can probably do something like this with even less code than I have.

While we’re here, let’s throw a big exception if the client sends us invalid JSON.

Leave a comment!

3
Login or Register to join the conversation
Default user avatar
Default user avatar Maksym Minenko | posted 5 years ago

Any plans to actually create a tutorial on the Silex framework?

Reply

Hey Maksym,

We have plans to create Silex tutorial, but have no any estimates on it yet. For now, you can check out a few course based on Silex: check "SIlex" tag on https://knpuniversity.com/c... page.

Cheers!

Reply
Default user avatar
Default user avatar Maksym Minenko | Victor | posted 5 years ago

Well, both Rest part are kind of heavy for me, frankly speaking... And they doesn't dwell on Silex *at all*.
I guess I'll try "OAuth2 in 8 Steps", though.

Reply
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
    }
}
userVoice