@@ -34,6 +34,7 @@ backed by ActiveRecord models or by custom objects.
3434 * [ Handling Exceptions] (#handling-exceptions)
3535 * [ Action Callbacks] (#action-callbacks)
3636 * [ Serializer] (#serializer)
37+ * [ Routing] (#routing)
3738* [ Configuration] (#configuration)
3839* [ Contributing] (#contributing)
3940* [ License] (#license)
@@ -1368,7 +1369,158 @@ JSONAPI::ResourceSerializer.new(PostResource, include: include_resources,
13681369).serialize_to_hash(PostResource .new (post, nil ))
13691370```
13701371
1371- #### Routing
1372+ #### Formatting
1373+
1374+ JR by default uses some simple rules to format (and unformat) an attribute for (de-)serialization. Strings and Integers are output to JSON
1375+ as is, and all other values have ` .to_s ` applied to them. This outputs something in all cases, but it is certainly not
1376+ correct for every situation.
1377+
1378+ If you want to change the way an attribute is (de-)serialized you have a couple of ways. The simplest method is to create a
1379+ getter (and setter) method on the resource which overrides the attribute and apply the (un-)formatting there. For example:
1380+
1381+ ``` ruby
1382+ class PersonResource < JSONAPI ::Resource
1383+ attributes :name , :email , :last_login_time
1384+
1385+ # Setter example
1386+ def email= (new_email )
1387+ @model .email = new_email.downcase
1388+ end
1389+
1390+ # Getter example
1391+ def last_login_time
1392+ @model .last_login_time.in_time_zone(@context [:current_user ].time_zone).to_s
1393+ end
1394+ end
1395+ ```
1396+
1397+ This is simple to implement for a one off situation, but not for example if you want to apply the same formatting rules
1398+ to all DateTime fields in your system. Another issue is the attribute on the resource will always return a formatted
1399+ response, whether you want it or not.
1400+
1401+ ##### Value Formatters
1402+
1403+ To overcome the above limitations JR uses Value Formatters. Value Formatters allow you to control the way values are
1404+ handled for an attribute. The ` format ` can be set per attribute as it is declared in the resource. For example:
1405+
1406+ ``` ruby
1407+ class PersonResource < JSONAPI ::Resource
1408+ attributes :name , :email , :spoken_languages
1409+ attribute :last_login_time , format: :date_with_utc_timezone
1410+
1411+ # Getter/Setter for spoken_languages ...
1412+ end
1413+ ```
1414+
1415+ A Value formatter has a ` format ` and an ` unformat ` method. Here's the base ValueFormatter and DefaultValueFormatter for
1416+ reference:
1417+
1418+ ``` ruby
1419+ module JSONAPI
1420+ class ValueFormatter < Formatter
1421+ class << self
1422+ def format (raw_value )
1423+ super (raw_value)
1424+ end
1425+
1426+ def unformat (value )
1427+ super (value)
1428+ end
1429+ ...
1430+ end
1431+ end
1432+ end
1433+
1434+ class DefaultValueFormatter < JSONAPI ::ValueFormatter
1435+ class << self
1436+ def format (raw_value )
1437+ case raw_value
1438+ when String , Integer
1439+ return raw_value
1440+ else
1441+ return raw_value.to_s
1442+ end
1443+ end
1444+ end
1445+ end
1446+ ```
1447+
1448+ You can also create your own Value Formatter. Value Formatters must be named with the ` format ` name followed by
1449+ ` ValueFormatter ` , i.e. ` DateWithUTCTimezoneValueFormatter ` and derive from ` JSONAPI::ValueFormatter ` . It is
1450+ recommended that you create a directory for your formatters, called ` formatters ` .
1451+
1452+ The ` format ` method is called by the ` ResourceSerializer ` as is serializing a resource. The format method takes the
1453+ ` raw_value ` parameter. ` raw_value ` is the value as read from the model.
1454+
1455+ The ` unformat ` method is called when processing the request. Each incoming attribute (except ` links ` ) are run through
1456+ the ` unformat ` method. The ` unformat ` method takes a ` value ` , which is the value as it comes in on the
1457+ request. This allows you process the incoming value to alter its state before it is stored in the model.
1458+
1459+ ###### Use a Different Default Value Formatter
1460+
1461+ Another way to handle formatting is to set a different default value formatter. This will affect all attributes that do
1462+ not have a ` format ` set. You can do this by overriding the ` default_attribute_options ` method for a resource (or a base
1463+ resource for a system wide change).
1464+
1465+ ``` ruby
1466+ def default_attribute_options
1467+ {format: :my_default }
1468+ end
1469+ ```
1470+
1471+ and
1472+
1473+ ``` ruby
1474+ class MyDefaultValueFormatter < JSONAPI ::ValueFormatter
1475+ class << self
1476+ def format (raw_value )
1477+ case raw_value
1478+ when String , Integer
1479+ return raw_value
1480+ when DateTime
1481+ return raw_value.in_time_zone(' UTC' ).to_s
1482+ else
1483+ return raw_value.to_s
1484+ end
1485+ end
1486+ end
1487+ end
1488+ ```
1489+
1490+ This way all DateTime values will be formatted to display in the UTC timezone.
1491+
1492+ #### Key Format
1493+
1494+ By default JR uses dasherized keys as per the
1495+ [ JSON API naming recommendations] ( http://jsonapi.org/recommendations/#naming ) . This can be changed by specifying a
1496+ different key formatter.
1497+
1498+ For example, to use camel cased keys with an initial lowercase character (JSON's default) create an initializer and add
1499+ the following:
1500+
1501+ ``` ruby
1502+ JSONAPI .configure do |config |
1503+ # built in key format options are :underscored_key, :camelized_key and :dasherized_key
1504+ config.json_key_format = :camelized_key
1505+ end
1506+ ```
1507+
1508+ This will cause the serializer to use the ` CamelizedKeyFormatter ` . You can also create your own ` KeyFormatter ` , for
1509+ example:
1510+
1511+ ``` ruby
1512+ class UpperCamelizedKeyFormatter < JSONAPI ::KeyFormatter
1513+ class << self
1514+ def format (key )
1515+ super .camelize(:upper )
1516+ end
1517+ end
1518+ end
1519+ ```
1520+
1521+ You would specify this in ` JSONAPI.configure ` as ` :upper_camelized ` .
1522+
1523+ ### Routing
13721524
13731525JR has a couple of helper methods available to assist you with setting up routes.
13741526
@@ -1535,157 +1687,6 @@ phone_number_contact GET /phone-numbers/:phone_number_id/contact(.:format) co
15351687
15361688```
15371689
1538- #### Formatting
1539-
1540- JR by default uses some simple rules to format (and unformat) an attribute for (de-)serialization. Strings and Integers are output to JSON
1541- as is, and all other values have ` .to_s ` applied to them. This outputs something in all cases, but it is certainly not
1542- correct for every situation.
1543-
1544- If you want to change the way an attribute is (de-)serialized you have a couple of ways. The simplest method is to create a
1545- getter (and setter) method on the resource which overrides the attribute and apply the (un-)formatting there. For example:
1546-
1547- ``` ruby
1548- class PersonResource < JSONAPI ::Resource
1549- attributes :name , :email , :last_login_time
1550-
1551- # Setter example
1552- def email= (new_email )
1553- @model .email = new_email.downcase
1554- end
1555-
1556- # Getter example
1557- def last_login_time
1558- @model .last_login_time.in_time_zone(@context [:current_user ].time_zone).to_s
1559- end
1560- end
1561- ```
1562-
1563- This is simple to implement for a one off situation, but not for example if you want to apply the same formatting rules
1564- to all DateTime fields in your system. Another issue is the attribute on the resource will always return a formatted
1565- response, whether you want it or not.
1566-
1567- ##### Value Formatters
1568-
1569- To overcome the above limitations JR uses Value Formatters. Value Formatters allow you to control the way values are
1570- handled for an attribute. The ` format ` can be set per attribute as it is declared in the resource. For example:
1571-
1572- ``` ruby
1573- class PersonResource < JSONAPI ::Resource
1574- attributes :name , :email , :spoken_languages
1575- attribute :last_login_time , format: :date_with_utc_timezone
1576-
1577- # Getter/Setter for spoken_languages ...
1578- end
1579- ```
1580-
1581- A Value formatter has a ` format ` and an ` unformat ` method. Here's the base ValueFormatter and DefaultValueFormatter for
1582- reference:
1583-
1584- ``` ruby
1585- module JSONAPI
1586- class ValueFormatter < Formatter
1587- class << self
1588- def format (raw_value )
1589- super (raw_value)
1590- end
1591-
1592- def unformat (value )
1593- super (value)
1594- end
1595- ...
1596- end
1597- end
1598- end
1599-
1600- class DefaultValueFormatter < JSONAPI ::ValueFormatter
1601- class << self
1602- def format (raw_value )
1603- case raw_value
1604- when String , Integer
1605- return raw_value
1606- else
1607- return raw_value.to_s
1608- end
1609- end
1610- end
1611- end
1612- ```
1613-
1614- You can also create your own Value Formatter. Value Formatters must be named with the ` format ` name followed by
1615- ` ValueFormatter ` , i.e. ` DateWithUTCTimezoneValueFormatter ` and derive from ` JSONAPI::ValueFormatter ` . It is
1616- recommended that you create a directory for your formatters, called ` formatters ` .
1617-
1618- The ` format ` method is called by the ` ResourceSerializer ` as is serializing a resource. The format method takes the
1619- ` raw_value ` parameter. ` raw_value ` is the value as read from the model.
1620-
1621- The ` unformat ` method is called when processing the request. Each incoming attribute (except ` links ` ) are run through
1622- the ` unformat ` method. The ` unformat ` method takes a ` value ` , which is the value as it comes in on the
1623- request. This allows you process the incoming value to alter its state before it is stored in the model.
1624-
1625- ###### Use a Different Default Value Formatter
1626-
1627- Another way to handle formatting is to set a different default value formatter. This will affect all attributes that do
1628- not have a ` format ` set. You can do this by overriding the ` default_attribute_options ` method for a resource (or a base
1629- resource for a system wide change).
1630-
1631- ``` ruby
1632- def default_attribute_options
1633- {format: :my_default }
1634- end
1635- ```
1636-
1637- and
1638-
1639- ``` ruby
1640- class MyDefaultValueFormatter < JSONAPI ::ValueFormatter
1641- class << self
1642- def format (raw_value )
1643- case raw_value
1644- when String , Integer
1645- return raw_value
1646- when DateTime
1647- return raw_value.in_time_zone(' UTC' ).to_s
1648- else
1649- return raw_value.to_s
1650- end
1651- end
1652- end
1653- end
1654- ```
1655-
1656- This way all DateTime values will be formatted to display in the UTC timezone.
1657-
1658- #### Key Format
1659-
1660- By default JR uses dasherized keys as per the
1661- [ JSON API naming recommendations] ( http://jsonapi.org/recommendations/#naming ) . This can be changed by specifying a
1662- different key formatter.
1663-
1664- For example, to use camel cased keys with an initial lowercase character (JSON's default) create an initializer and add
1665- the following:
1666-
1667- ``` ruby
1668- JSONAPI .configure do |config |
1669- # built in key format options are :underscored_key, :camelized_key and :dasherized_key
1670- config.json_key_format = :camelized_key
1671- end
1672- ```
1673-
1674- This will cause the serializer to use the ` CamelizedKeyFormatter ` . You can also create your own ` KeyFormatter ` , for
1675- example:
1676-
1677- ``` ruby
1678- class UpperCamelizedKeyFormatter < JSONAPI ::KeyFormatter
1679- class << self
1680- def format (key )
1681- super .camelize(:upper )
1682- end
1683- end
1684- end
1685- ```
1686-
1687- You would specify this in ` JSONAPI.configure ` as ` :upper_camelized ` .
1688-
16891690## Configuration
16901691
16911692JR has a few configuration options. Some have already been mentioned above. To set configuration options create an
0 commit comments