Skip to content

Commit 6e816bf

Browse files
committed
Move Routing section and add to README ToC
Promote the Routing section of the README to an H3, move it out of (what looks like) the middle of the Serializer section, and add it to the ToC.
1 parent bf2705b commit 6e816bf

1 file changed

Lines changed: 153 additions & 152 deletions

File tree

README.md

Lines changed: 153 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -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

13731525
JR 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

16911692
JR has a few configuration options. Some have already been mentioned above. To set configuration options create an

0 commit comments

Comments
 (0)