2

I'm starting with Zend Framework 3 and I saw an example on the tutorial that goes like this:

public function addAction()
{
    $form = new AlbumForm();
    $form->get('submit')->setValue('Add');

    $request = $this->getRequest();

    if (! $request->isPost()) {       // <-------------- HERE!!!!
        return ['form' => $form];
    }

    $album = new Album();
    $form->setInputFilter($album->getInputFilter());
    $form->setData($request->getPost());

    if (! $form->isValid()) {
        return ['form' => $form];
    }

    $album->exchangeArray($form->getData());
    $this->table->saveAlbum($album);
    return $this->redirect()->toRoute('album');
}

Now, considering what Robert C. Martin says about SRP (from wikipedia):

A class or module should have one, and only one, reason to change.

From my perspective, given the specifications for the creation form changes (maybe we now have to load data in a dropdown box) this would affect the GET request. However, given the specification for a redirection changes (we now redirect to /index instead of /details) this would affect the POST request.

Since both are in the same method, does this violates SRP, or am I missing something?

Disclaimer: I come from Laravel, where we have 1 method for each request; so having a check like if($request->isPost) {} feels wrong. But this is official Zend Framework 3 documentation, so maybe I'm missing something.

  • 2
    SRP doesn't mean "Do one thing." It means "Have one concern." (as in "separation of concerns") – Robert Harvey Sep 21 '16 at 21:53
  • @RobertHarvey could you expand a little bit more please? – Christopher Francisco Sep 22 '16 at 3:00
  • @ChristopherFrancisco A method or a class can do many things, as long as those things are on the same level of abstraction for the same concept, it respects the SRP. For example, you could manage authentication of users with high level validation, along with high level error returning (with business rules ie 6 letters min for password), and then validation could be done at a lower level with database (does user and password match in DB). As you can see, validating everything in the same method would be a bad choice here because the levels of abstraction would be merged, thus violate SRP. – Steve Chamaillard Sep 22 '16 at 12:37
2

I may be misunderstanding, but it seems there are two questions here: one about HTTP endpoint design, and another about function design.

Endpoints

I am not familiar with PHP, nor the Zend Framework. But in designing a REST(ish) API, it is quite common to have an endpoint api.mysite/users representing a collection (in this case of users). A GET to said endpoint would return a collection of all the users, and a POST to the endpoint would create a new user.

I cannot read your code, so I can't tell whether this is the case for you. But in general, different verbs on a single endpoint should be related.

Functions

I come from Laravel, where we have 1 method for each request; so having a check like if($request->isPost) {} feels wrong.

You're correct. In fact, a boolean-valued function isPost is wrong. The correct approach would be to have a method getRequestMethod that returns an enumeration - or in languages which lack such support, a string (shudders). The case statement would defer to the appropriate method. Of course, this logic could be taken care of behind the scenes, and then you would just fill in the appropriate get, post, functions etc (I use a framework that takes this approach).

  • Thanks for your answer. However, my concern isn't about REST API design. It's whether using the same object's method (method as in a Class method, not http verb) to handle both POST and GET requests violates SRP. The example is meant to indicate that GET is handled outside of the if-statement where POST is handled inside it. – Christopher Francisco Sep 22 '16 at 2:57
  • That means your method will 'Manage the route as GET protocol and as POST protocol'. This 'and' shows it breaks SRP. Also that means this method will change if the logic with either GET or POST protocol changes, which is another indication that it breaks SRP, it has more than one reason to change. – Steve Chamaillard Sep 22 '16 at 10:16
  • Oops, I meant to answer that. I updated my answer accordingly. No, one method should not handle both POST and GET. – gardenhead Sep 22 '16 at 15:13
  • The problem with saying no is that you then needs to show how it should be done. Keep in mind that a posted form needs to be tested for validity and if the validity check fails the form needs to be shown with the incorrect data highlighted. Doing this with two methods is awkward to say the least. Here is a better example of why processing both get and post in one method is fine: symfony.com/doc/current/forms.html#handling-form-submissions – Cerad Sep 22 '16 at 17:03
  • I said how it should be done. There should be different functions for both POST and GET. I don't understand your example. If a user POSTs with incorrect data, then the response body should indicate such error. Servers can respond to both POST and GET requests. – gardenhead Sep 22 '16 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.