1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Example of an ad hoc serializer that is tailored to transform business specific objects into customized representation.
17 # In the following, we expose 3 business classes, `E`, `A` and `B`, and a specific business serializer `RestrictedSerializer`.
18 # The principle is that the custom serialization logic in enclosed into the `RestrictedSerializer` and that the
19 # standard serializer is unchanged.
21 # The additional behaviors exposed are:
23 # * replace a full business object (see `E::id`):
24 # instead of serializing an attribute, the custom serializer uses a different representation.
25 # * inject a phantom attribute (see `E::phantom`):
26 # when serializing, the custom serializer injects new attributes.
27 # * hide a normally serialized attribute (see `E::semi_private`):
28 # when serializing, the custom serializer hides some specific attributes.
30 # The advantage of the approach is that it is done programmatically so can be adapted to real complex use cases.
31 # Basically, this is half-way between the full automatic serialization and the full manual serialisation.
32 module custom_serialization
is example
35 import json
::serialization_write
37 # The root class of the business objects.
38 # This factorizes most services and domain knowledge used by the `RestrictedSerializer`
40 # In real enterprise-level code, the various specific behaviors can be specified in more semantic classifiers.
44 # The semantic business identifier.
46 # With the `RestrictedSerializer`, references to `E` objects will be replaced with `id`-based information.
47 # This avoid to duplicate or enlarge the information cross-call wise.
49 # A future API/REST call can then request the _missing_ object from its identifier.
52 # A phantom attribute to be serialized by the custom `RestrictedSerializer`.
54 # This can be used to inject constant or computed information that make little sense to have as a genuine attribute in
56 fun phantom
: String do return "So Much Fun"
58 # An attribute not to be serialized by the custom `RestrictedSerializer`.
59 # e.g. we want it on the DB but not in API/REST JSON messages
61 # Note that the annotation `noserialize` hides the attribute for all serializers.
62 # To hide the attribute only in the `RestrictedSerializer`, it will have to actively ignore it.
63 var semi_private
= "secret"
65 # Test method that serializes `self` and prints with the standard JsonSerializer
68 var w
= new StringWriter
69 var js
= new JsonSerializer(w
)
75 # Test method that serializes `self` and prints with the custom RestrictedJsonSerializer.
78 var w
= new StringWriter
79 var js
= new RestrictedJsonSerializer(w
)
86 # Extends Serializer and adds specific business behaviors when dealing with business objects.
88 # As with standard Nit, additional level of customization can be achieved by adding more double-dispatching :)
89 # We can thus choose to locate the specific behavior in the serializer, or the serializees.
90 class RestrictedSerializer
93 # This method is called to generate the attributes of a serialized representation
94 redef fun serialize_core
(value
)
99 # Inject additional special domain-specific information
100 serialize_attribute
("more-data", value
.phantom
)
104 # This method is called when trying to serialize a specific attribute
105 redef fun serialize_attribute
(name
, value
)
107 var recv
= current_object
109 # do not serialize `E::semi_private`
110 if name
== "semi_private" then return
114 # Do not serialize references to `E`.
115 # Just use a domain-specific value that make sense in the business logic.
116 serialize_attribute
(name
, "ID:" + value
.id
)
124 # Extends JsonSerializer and adds specific business behaviors when dealing with business objects.
125 class RestrictedJsonSerializer
127 super RestrictedSerializer
130 # A business object, with an integer information
135 # A business information
139 # A business object associated with an `A`.
144 # A business association
148 # The business data to serialize
149 var a
= new A
("a", 1)
150 var b
= new B
("b", a
)