Stephen,
First some quick history about this. The special DSL for headers was initially built for a couple of reasons:
- To accommodate the common case where header values need to be handled as pure, unmodifyed strings
- To simplify their definition and avoid all the complexity of defining :required, possible values, regexps through the hash set of options.
Even beyond that, the fact that we reuse an Attributor::Attribute to store load and dump each header is actually hidden from the users.
What this means is that underneath, the current DSL really does the following:
- header :Foo (i.e., a header named Foo must exist in the request)
- maps to: attribute String, required: true
- header :Baz , "some_value" (i.e., if a header named Baz exists, it must match "some_value" string)
- maps to: attribute String, values: ["some_value"]
- header :Bar, /pattern/ (i.e., if a header named Bar exists, it must match the /pattern/ regexp)
- maps to: attribute String, regexp: /pattern/
More concise and less verbose. Now, this headers syntax, also allows passing any extra options, and those will be applied to the underlying attribute. For example, you could express that the Bar header should not only match the /pattern/ but that also should exist by: header :Bar, /pattern/ , required: true
So suddenly, the simplicity starts becoming a little less clear...
So, while this case made sense for simplifying 99% of the header definitions, the current pervasiveness of the Attributor syntax in the ResourceDefinitions might make that simplification less "interesting", like you're pointing out. In fact, after thinking about it, I see no reason not to create a URI attributor type, and using wholesale in headers like Location, so that by the time it makes it to the app we have a nicely loaded and validated type ready to go...no need to make the app convert the string on its own.
For example:
- attribute :Location, Attributor::URI, required: true
Also, I'm not keen on having different ways to do the same thing, unless there is a massive gain, so I wouldn't advocate to support both ways, at least from the get go. The way we can inject DSL definitions for attributor blocks leaves the door open to change and add new methods in the future. So, I think I'm buying the approach of ditching the special DSL "header" in lieu of a normal, full fledged attribute syntax. More verbose, but already a familiar syntax, and also potentially more powerful for the intrepid devs :)
I'm interested in hearing what are the other people thoughts.
Josep M.