English spoken conference

New in Symfony 4.3: URL Env Var Processor

Contributed by
Jérémy Derussé
in #28975.

When using env vars to configure Symfony it's common to use URLs to define the value of DSN-like config options like the following:

1
2
# .env
MONGODB_URL="mongodb://db_user:[email protected]:27017/db_name"

However, sometimes you need to access to some parts of the URL (such as the database name or the port number) to define the value of other options. In Symfony 4.3, we've added two new env var processors (url and query_string) to do that.

The url processor parses the given URL and returns an associative array with its components, so you can combine it with the key processor:

  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    # config/packages/mongodb.yaml
    mongo_db_bundle:
        clients:
            default:
                # ...
                username: '%env(key:user:url:MONGODB_URL)%'
                password: '%env(key:pass:url:MONGODB_URL)%'
        connections:
            default:
                database_name: '%env(key:path:url:MONGODB_URL)%'
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    <!-- config/packages/mongodb.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd">
        <mongodb:config>
            <mongodb:client name="default"
             username="%env(key:user:url:MONGODB_URL)%"
             password="%env(key:pass:url:MONGODB_URL)%">
                <!-- ... -->
            </mongodb:client>
            <mongodb:connections name="default"
             database_name="%env(key:path:url:MONGODB_URL)%"/>
        </mongodb:config>
    </container>
    

The query_string processor parses the query string part of the given URL and returns an associative array with its components, so you can also combine it with the key processor. If the env var is defined like this:

1
2
# .env
MONGODB_URL="mongodb://db_user:[email protected]:27017/db_name?timeout=3000"

You can get the value of the timeout parameter of the query string as follows:

  • YAML
    1
    2
    3
    4
    5
    6
    # config/packages/mongodb.yaml
    mongo_db_bundle:
        clients:
            default:
                # ...
                connectTimeoutMS: '%env(int:key:timeout:query_string:MONGODB_URL)%'
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    <!-- config/packages/mongodb.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd">
        <mongodb:config>
            <mongodb:client name="default"
             connectTimeoutMS="%env(int:key:timeout:query_string:MONGODB_URL)%" />
        </mongodb:config>
    </container>
    

Comments

👍 Well, it was lacking.
Looking great!
The new DSN-like configuration surprised me, because it's easier to concatenate strings than the other way around.

A method to undo the concatenation if great, but it feels like a dirty workaround for a problem that doesn't have to (and even didn't?) exist in the first place. What's wrong with setting username/password as environment variables?
@Stephan there's nothing wrong with setting several env vars for each part (username, password, database name, port, etc.) You can still do that in newer Symfony versions.

However, it's increasingly common for Internet services to use DSN-like URLs to configure things. That's why Symfony supports it and makes it easy to work with that.
@Stephan: It is more practical to use one env variable to configure database access than using many variables and adding more when additional parameter (encoding, protocol version,...) is required. I don't like it in config files, but it makes sense in env variables. This change looks like it brings better of both.
awesome...

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.