Abstracting Request Keys

March 2018

In an API’s codebase, it's a good idea to abstract the keys for the requests and responses on top of your data layer. This is a key step to making it easier for your codebase to evolve and still uphold your API contract.

In Laravel we have Resource Responses to help abstract our model data for responses. For request data, I wanted a lightweight key mapping to help add a little abstraction layer.

First I created a little Request macro:

Request::macro('mapKeys', function ($keyMap) {
    collect($this->all())
        ->each(function ($attribute, $key) use ($keyMap) {
            if (array_key_exists($key, $keyMap)) {
                $this->json->set($keyMap[$key], $attribute);
            }
        });
    return $this;
});

Now you can use it in your controllers to map from request data to domain data.

public function store()
{
    $this->authorizeConsumer('accounts.store');

    return AccountResource::make(Account::create(request()
        ->mapKeys([
            'gateway_username' => 'username',
            'gateway_password' => 'password'
        ])
        ->valdate([
            'username' => 'required',
            'password' => 'required',
            'environment' => 'required|in:production,sandbox',
        ])));
}

One thing I’ll still need to figure out is mutating nested keys, but I’ll cross that bridge when I get there!