mtwilliams / blazon Goto Github PK
View Code? Open in Web Editor NEW:beginner: Declarative abstract serializers for Elixir.
License: Other
:beginner: Declarative abstract serializers for Elixir.
License: Other
This could/should be handled about another package, say blazon_auto_cache
.
It would cache based on the input objects and options. It would likely need a key to disambiguate objects, which could be deduced from Ecto schema or manually specified via an option.
This would wrap immediate values in something like &(Map.get(&1, <field>))
. More sophisticated fetching would have the same interface. This could be extended to allow wrapping in another fun (monadic!) to implement #21 for example.
We don't special-case the intermediate representation.
Given something like,
defmodule Person do
defstruct ~w(name)a
end
defmodule PersonSerializer do
use Blazon.Serializable
field name, :string
field gender, enum: [type: :gender, ~w(male female)a], via: fn (person) ->
if String.contains?("John")
:male
else
:female
end
end
end
We should produce an intermediate form like so:
iex(1)> Blazon.intermediate([PersonSerializer], [%Person{name: "John Doe"}, %Person{name: "Jane Doe"}])
{[[{:name, [type: :string], "John Doe"},
{:gender, [type: {:enum, [name: :gender], [:male, :female]}], :male}],
[{:name, [type: :string], "Jane Doe"},
{:gender, [type: {:enum, [name: :gender], [:male, :female]}], :female}],
[type: [People]]}
This will allow more structured serializers i.e. xml
to provide proper type semantics.
Instead of providing field(name, options \\ [])
we should provide field(name, type, options \\ [])
.
This way one compilation failure won't ruin the entire test suite.
Instead of calling Blazon.to_map
, we should just call Blazon.map
.
This is the natural conclusion of allowing collections. Take for example,
defmodule Person do
defstruct ~w(name)a
end
defmodule PersonSerializer do
use Blazon.Serializable
field name, :string
field gender, :boolean, via: fn (person) ->
if String.contains?("John")
:male
else
:female
end
end
end
We could serialize a list of people by doing:
iex(1)> Blazon.map([PersonSerializer], [%Person{name: "John Doe"}, %Person{name: "Jane Doe"}])
[%{name: "John Doe", gender: :male}, %{name: "Jane Doe", gender: :female}]
...but what if we want to handle paginated results?
iex(2)> [%Person{name: "John Doe"}, %Person{name: "Jane Doe"}];
nil
iex(3)> Blazon.map(%{page: :integer, per_page: :integer, ..., results: [PeopleSerializer]}, %{page: 1, per_page: 100, ..., results: people})
%{page: 1, per_page: 100, ..., [%{name: "John Doe", gender: :male}, %{name: "Jane Doe", gender: :female}]}
We end up with semantics akin to Poison. This allows for creative composition of serializers that promotes overall understandability and reuse. For example, we could refactor that paginated serialization into:
def paginated(type_or_serializer, results \\ :results) do
%{page: :integer, per_page: :integer, ..., results => [type_or_serializer]}
end
Blazon.map(paginated(PeopleSerializer, :people), [people])
Not even viewer-dependent serialization should require more than one serializer per type. Moving to protocols vastly simplifies the codebase, and should improve performance.
Can we provide a fallback mechanism for tertiary serializers?
Perhaps via a blazon_and_ecto
package?
Specifically around different serializers, like Blazon.Serializers.JSON
.
Being able to re-use your serializers (that perform type checking) is... bloody useful.
Having logic for hidden fields that we don't normally expose unless explicitly requested is really useful.
To start, what "fields" will be serialized.
This will collate all options parsing, thereby reducing bugs. It will also make handling of preloading much easier โ don't need to preload data for fields that won't be serialized.
We should expose options that allow for different on-the-wire formatting.
This will require a hand-implementation of the protocol or Blazon.Serializable
semantics. Which implies (potentially) a stabilized "standard" for semantics if we don't decide to use protocols.
By allowing certain fields to be extracted?
This brings up an important question: should Blazon provide a way to generate a schema?
There's a lot of uses cases where this makes sense. It is especially useful when building a RESTful API to allow denormalization to reduce the number of round trips.
Blazon.serialize(playlist, expand: ~w(songs)a)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.