Stripe.Entity behaviour (stripity_stripe v2.17.2) View Source

A behaviour implemented by modules which represent Stripe objects.

Intended for internal use within the library.

A Stripe Entity is just a struct, optionally containing some logic for transforming a raw result from the Stripe API into a final struct. This is achieved through the use of the from_json/2 macro.

The list of objects which are recognised by the library upon receipt are currently static and contained in Stripe.Converter.

When a map containing the "object" key is received from the API (even when nested inside another map), and the value of that field (for example, "foo_widget") is in the list of supported objects, the converter will expect Stripe.FooWidget to be present and to implement this behaviour.

To implement this behaviour, simply add use Stripe.Entity to the top of the entity module and make sure it defines a struct. This will also enable the use of the from_json/2 macro, which allows for changes to the data received from Stripe before it is converted to a struct.

Link to this section Summary

Functions

Applies the given function over a list present in the data.

Applies the given function to a field accessed via the path provided.

Cast the value of the given key or keys to an atom.

Specifies logic that transforms data from Stripe to our Stripe object.

Link to this section Callbacks

Specs

__from_json__(data :: map()) :: map()

Link to this section Functions

Link to this function

cast_each(data, keys, fun)

View Source

Specs

cast_each(map(), atom() | [atom()], (any() -> any())) :: map()

Applies the given function over a list present in the data.

Provide either a single atom key or a list of atom keys whose values are lists. Each element of such a list will be mapped using the function passed.

For example, if there is a field :fee_details which is a list of maps, each containing a :type key whose value we want to cast to an atom, then we write:

data
|> cast_each(:fee_details, &cast_to_atom(&1, :type))

If a key is not set or the value is nil, no transformation occurs.

Link to this function

cast_path(data, path, fun)

View Source

Specs

cast_path(map(), [atom()], (any() -> any())) :: map()

Applies the given function to a field accessed via the path provided.

Provide a path (identical to that used by the Access protocol) to the field to be modified, and a function to be applied to its value. For example, if the field :fraud_details contains a map whose keys are :user_report and :stripe_report we wish to convert to atoms, then we write:

data
|> cast_path([:fraud_details], &cast_to_atom(&1, [:user_report, :stripe_report]))

Unlike Kernel.update_in/2, if the path to the key does not exist, or if the value is nil, then no transformation occurs.

Link to this function

cast_to_atom(data, keys)

View Source

Specs

cast_to_atom(map(), atom() | [atom()]) :: map()

Cast the value of the given key or keys to an atom.

Provide either a single atom key or a list of atom keys whose values should be converted from binaries to atoms. Used commonly to convert "enum" values (values which belong to a predefined set) in Stripe responses, for example a :status field.

If a key is not set or the value is nil, no transformation occurs.

Link to this macro

from_json(param, list)

View Source (macro)

Specifies logic that transforms data from Stripe to our Stripe object.

The Stripe API docs specify that:

JSON is returned by all API responses, including errors, although our API libraries convert responses to appropriate language-specific objects.

To this end, sometimes it is desirable to make changes to the raw data received from the Stripe API, to aid its conversion into an appropriate Elixir data struct.

One example is the convention of converting "enum" values (for example "status" values of "succeeded" or "failed") into atoms instead of keeping them as strings.

This macro is used in modules implementing the Stripe.Entity behaviour in order to specify this extra logic.

Its use is optional, and the default is no transformation; i.e. the received JSON keys are merely converted to atoms and cast to the struct defined by the module.

The macro is used like this:

from_json data do
  data
  |> cast_to_atom([:type, :status])
  |> cast_each(:fee_details, &cast_to_atom(&1, :type))
end

It takes a parameter name to which the data received from Stripe is bound, and a do block which should return the transformed data. The transformation receives the JSON response from Stripe, with all keys converted to atoms (apart from keys inside a metadata map, which remain binaries) and should return a map which is ready to be cast to the struct the module defines.

The helper cast_* functions defined in this module are automatically imported into the scope of this macro.

The helper functions are all nil/missing key-safe, meaning that they will not magically add fields or error on fields which are missing or unset. You should therefore write your transformation assuming all possible data is actually present.