Packages
ash_json_api
1.6.6
1.7.1
1.7.0
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0-rc.2
1.6.0-rc.1
1.6.0-rc.0
1.5.1
1.5.0
1.4.45
1.4.44
1.4.43
1.4.42
1.4.41
1.4.40
1.4.39
1.4.38
1.4.37
1.4.36
1.4.35
1.4.34
1.4.33
1.4.32
1.4.31
1.4.30
1.4.29
1.4.28
1.4.27
1.4.26
1.4.25
1.4.24
1.4.23
1.4.22
1.4.21
1.4.20
1.4.19
1.4.18
1.4.17
1.4.16
1.4.15
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.8
1.3.7
1.3.6
1.3.5
1.3.4
retired
1.3.3
1.3.2
1.3.1
1.3.0
1.2.2
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-rc.6
1.0.0-rc.5
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.34.2
0.34.1
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.3
0.31.2
retired
0.31.1
0.31.0
0.30.1
0.30.0-rc.4
0.30.0-rc.3
0.30.0-rc.2
0.30.0-rc.1
0.30.0-rc.0
0.29.1
0.29.0
0.28.6
0.28.5
0.28.4
0.28.3
0.28.2
0.28.1
0.28.0
0.27.6
0.27.5
0.27.1
0.27.0
0.25.0
0.24.4
0.24.2
0.24.1
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.1
0.10.0
0.9.0
0.8.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.4
0.2.3
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
The JSON:API extension for the Ash Framework.
Current section
Files
Jump to
Current section
Files
documentation/topics/field-names.md
<!--
SPDX-FileCopyrightText: 2020 Zach Daniel
SPDX-License-Identifier: MIT
-->
# Transforming Field Names
By default, AshJsonApi uses the Ash resource's attribute, relationship, calculation, and aggregate names directly as JSON:API field names. This means a `:first_name` attribute appears as `"first_name"` in requests and responses. The `field_names` and `argument_names` DSL options let you change this — for example, to expose a camelCase API while keeping snake_case internals.
These options affect **every** place a field or argument name appears: serialization output, request body parsing, sort and filter parameters, sparse fieldsets, error source pointers, relationship keys, JSON Schema, and OpenAPI spec generation.
## Renaming fields
### Built-in transformers
Use `:camelize` or `:dasherize` for common conventions:
```elixir
field_names :camelize # first_name → firstName
field_names :dasherize # first_name → first-name
```
### Keyword list
Use a keyword list to rename specific fields:
```elixir
json_api do
type "user"
field_names first_name: :firstName, last_name: :lastName
end
```
A `GET /users/:id` response would then return:
```json
{
"data": {
"type": "user",
"id": "...",
"attributes": {
"firstName": "Ada",
"lastName": "Lovelace"
}
}
}
```
Fields not listed in the keyword list keep their original names.
### Function
Use a 1-arity function for a blanket transformation. This is useful for converting all field names to camelCase:
```elixir
json_api do
type "user"
field_names fn name ->
camelized = name |> to_string() |> Macro.camelize()
{first, rest} = String.split_at(camelized, 1)
String.downcase(first) <> rest
end
end
```
This applies to all public attributes, relationships, calculations, and aggregates on the resource.
## Renaming action arguments
Action arguments (the values sent in the request body under `data.attributes`) can also be renamed with `argument_names`.
### Keyword list
Provide a nested keyword list keyed by action name:
```elixir
json_api do
type "post"
argument_names [
create: [publish_at: :publishAt],
update: [publish_at: :publishAt]
]
end
```
### Function
Use a 2-arity function that receives `(action_name, argument_name)`:
```elixir
json_api do
type "post"
argument_names fn _action_name, arg_name ->
camelized = arg_name |> to_string() |> Macro.camelize()
{first, rest} = String.split_at(camelized, 1)
String.downcase(first) <> rest
end
end
```
The `action_name` parameter lets you apply different mappings per action if needed.
## Where renaming is applied
Once configured, name mapping is applied consistently across:
- **Serialization** — response `attributes` and `relationships` objects use the renamed keys.
- **Request body parsing** — `data.attributes` keys in POST/PATCH bodies are expected under their renamed forms.
- **Sort parameters** — `?sort=firstName` works when `:first_name` is renamed to `firstName`.
- **Filter parameters** — `?filter[firstName]=Ada` maps back to the `:first_name` attribute via a ref transformer passed to `Ash.Filter.parse_input/3`.
- **Sparse fieldsets** — `?fields[user]=firstName,lastName` selects the renamed fields.
- **Error source pointers** — validation errors point to `/data/attributes/firstName` instead of `/data/attributes/first_name`.
- **JSON Schema & OpenAPI** — generated schemas use the renamed property names.
## Combining both options
You can use `field_names` and `argument_names` together. A common pattern is to camelCase everything:
```elixir
json_api do
type "user"
field_names :camelize
argument_names :camelize
end
```