Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Psr7 Http Message, why immutable?

Tags:

php

psr-7

I am looking at the PSR-7 interfaces and thinking of a way on how to implement them.

I've also been reading this blog post. Apparently the objects that implement the PSR-7 interfaces must be immutable.

So if I implement the withProtocolVersion method from MessageInterface then it would look something like this:

public function withProtocolVersion($version)
{
    if ( $this->protocol === $version )
    {
        return $this;
    }

    $new = clone $this;
    $new->protocol = $version;
    return $new;
}

My question really is, why immutable? Why not simply do a return $this;?

It's not that I'm concerned about the amount of memory it allocates, I just really do not see any benefit in keeping it immutable.

Like the blog posts says, when you do this:

$request = $request
    ->withMethod('POST')
    ->withUrl(new Url('http://example.org/')
    ->withHeader('Content-Type', 'text/plain');

Then four copies are created, but the end result in $request is the same as when I would simply use return $this, right?

Why is the decision made to keep it immutable. So why do I have to do a clone $this? What's the benefit of it?

I'm not really getting the idea begind it.

like image 851
Vivendi Avatar asked Jul 11 '15 19:07

Vivendi


People also ask

What is psr7?

PSR-7 is a set of common interfaces defined by PHP Framework Interop Group. These interfaces are representing HTTP messages, and URIs for use when communicating trough HTTP. Any web application using this set of interfaces is a PSR-7 application.

What PSR 15?

PSR-15 HTTP Middleware describes a common standard for HTTP middleware components using HTTP Messages defined by PSR-7. Currently, PSR-15 is a PHP Standards Recommendation of the Framework Interoperability Group (FIG).


1 Answers

I suggest you to read this document, where all the design choices are explained in detail.

In particular you should read the Why value objects? and the New instances vs returning $this sections.

The key points are the following:

In essence, modeling HTTP messages as value objects ensures the integrity of the message state, and prevents the need for bi-directional dependencies, which can often go out-of-sync or lead to debugging or performance issues.

and

These operations can be accomplished with value objects as well, with a number of benefits:

  • The original request state can be stored for retrieval by any consumer.
  • A default response state can be created with default headers and/or message body.

If you want to dig deeper, I'd recommend to look in the history of the fig mailing list (you can find it here), where there was a lot of discussion regarding the immutability of the objects

like image 113
marcosh Avatar answered Oct 02 '22 23:10

marcosh