Skip to main content

Traits

Sometimes one wants to reuse common definition functionality across your entire API, which can be applied across different endpoints and actions. Praxis has the concept of Traits, to achieve this goal.

Declaring a Trait

Traits are defined and registered through the ApiDefinition singleton. A trait definition requires a globally unique name and a block of DSL elements. The block is used to instantiate an instance of the Trait class that is registered on the ApiDefinition singleton with the given name. You can think of a trait as a copy-pasteable block of code that you can refer to by name.

Here are a couple of example trait definitions:

Praxis::ApiDefinition.define do
trait :data_range do
params do
attribute :start_at, DateTime
attribute :end_at, DateTime
end
end

trait :authenticated do
headers do
key "Auth-Token", String, required: true
end
end
end

The first example creates a trait named data_range which defines two incoming parameters, start_at and end_at. If you write an action that uses this trait, it would be as if you had added this params block directly to your action.

The second example creates a trait named authenticated. All it does is define a required header named Auth-Token for you to use in your actions.

Using a Trait

To use a trait, call the trait method from within your action or endpoint, and pass the name of the trait you want to use. That will essentially bring over the block defined by that trait, as if you were creating it in place.

class Blogs
include Praxis::EndpointDefinition

# the 'authenticated' trait will be applied to all actions.
trait :authenticated

action :index
# the 'data_range' trait will only be used by the index action
trait :data_range
end
end

In this case, all actions in the Blogs resource definition will have the Auth-Token header defined. The index action will have :start_at and :end_at params defined. You can think of trait :trait_name as a cut-and-paste mechanism which allows you to reuse common snippets of design-time code.