View Source Flint.Extensions.JSON (Flint v0.4.0)

Provides JSON encoding capabilities for Flint schemas with Go-like marshalling options.

This extension enhances Flint schemas with customizable JSON serialization options, allowing fine-grained control over how fields are represented in JSON output.

Usage

To use this extension, include it in your Flint schema:

defmodule MySchema do
  use Flint.Schema,
     extensions: [{JSON, json_module: :json}]  # Jason, or Poison
     #extensions: [JSON] # (defaults to Jason if no args passed)

  embedded_schema do
    # Schema fields...
  end
end

JSON Encoding Options

The following options can be specified for each field in your schema:

  • :name - Specifies a custom name for the field in the JSON output.
  • :omitempty - When set to true, omits the field from JSON output if its value is nil.
  • :ignore - When set to true, always excludes the field from JSON output.

Defining Options

Options are defined directly in your schema using the field macro:

embedded_schema do
  field :id, :string, name: "ID"
  field :title, :string, name: "Title", omitempty: true
  field :internal_data, :map, ignore: true
end

Example

defmodule Book do
  use Flint.Schema,
    extensions: [Embedded, Accessible, JSON]

  embedded_schema do
    field :id, :string, name: "ISBN"
    field :title, :string
    field :author, :string, omitempty: true
    field :price, :decimal, name: "SalePrice"
    field :internal_notes, :string, ignore: true
  end
end

book = %Book{
  id: "978-3-16-148410-0",
  title: "Example Book",
  author: nil,
  price: Decimal.new("29.99"),
  internal_notes: "Not for customer eyes"
}

Jason.encode!(book)
# Results in:
# {
#   "ISBN": "978-3-16-148410-0",
#   "title": "Example Book",
#   "SalePrice": "29.99"
# }

Note how the author field is omitted due to omitempty: true, the internal_notes field is ignored, and custom names are used for id and price.

Introspection

You can inspect the JSON options for a schema using the __schema__/1 function:

Book.__schema__(:extra_options)
# Returns:
# [
#   id: [name: "ISBN"],
#   title: [],
#   author: [omitempty: true],
#   price: [name: "SalePrice"],
#   internal_notes: [ignore: true]
# ]

This allows for runtime inspection and manipulation of JSON encoding behavior.

Implementation Details

This extension implements the Jason.Encoder protocol for your schema, automatically applying the specified options during JSON encoding. It leverages Flint's schema introspection capabilities to retrieve and apply the options.

The encoding process:

  1. Converts the struct to a map
  2. Applies the :name option to change key names
  3. Applies the :omitempty option to remove nil values
  4. Applies the :ignore option to exclude specified fields
  5. Encodes the resulting map to JSON

This approach provides a flexible and powerful way to control JSON serialization directly from your schema definition, promoting clean and maintainable code.