# `JSONAPIPlug.Resource`
[🔗](https://github.com/lucacorti/jsonapi_plug/blob/main/lib/jsonapi_plug/resource.ex#L1)

You can use any struct as a resource by deriving or directly implementing the `JSONAPIPlug.Resource` protocol:

```elixir
defmodule MyApp.User do
  @derive {
    JSONAPIPlug.Resource,
    type: "user",
    attributes: [:name, :surname, :username]
  }
  defstruct id: nil, name: nil, surname: nil, username: nil
end
```
See `t:options/0` for all available options you can pass to `@derive JSONAPIPlug.Resource`.

## Attributes

By default, the resulting JSON document consists of resources taken from your data.
Only resource attributes defined on the resource will be (de)serialized. You can customize
how attributes are handled by passing a keyword list of options:

```elixir
defmodule MyApp.User do
  @derive {
    JSONAPIPlug.Resource,
    type: "user",
    attributes: [
      username: nil,
      fullname: [deserialize: false]
    ]
  }
end
```

In this example we are defining a computed attribute by passing the `serialize` option a function reference.
Serialization functions take `resource` and `conn` as arguments and return the attribute value to be serialized.
The `deserialize` option set to `false` makes sure the attribute is not deserialized when receiving a request.

## Relationships

Relationships are defined by passing the `relationships` option to `use JSONAPIPlug.Resource`.

```elixir
defmodule MyApp.Post do
  @derive {
    JSONAPIPlug.Resource,
    type: "post",
    attributes: [:text, :body]
    relationships: [
      author: [resource: MyApp.UsersResource],
      comments: [many: true, resource: MyApp.CommentsResource]
    ]
  }
end

defmodule MyApp.CommentsResource do
  alias MyApp.UsersResource

  @derive {
    JSONAPIPlug.Resource,
    type: "comment",
    attributes: [:text]
    relationships: [post: [resource: MyApp.Post]]
  }
  defstruct text: nil, post: nil
end
```

When requesting `GET /posts?include=author`, if the author key is present on the data you pass from the
controller it will appear in the `included` section of the JSON:API response.

## Links

When rendering resource links, the default behaviour is to is to derive values for `host`, `port`
and `scheme` from the connection. If you need to use different values for some reason, you can override them
using `JSONAPIPlug.API` configuration options in your api configuration:

```elixir
config :my_app, MyApp.API, host: "adifferenthost.com"
```

# `field_name`

```elixir
@type field_name() :: atom()
```

Resource field name

The name of a Resource field (attribute or relationship)

# `options`

```elixir
@type options() :: keyword()
```

Resource options

Available options:
* `:attributes` - Resource attributes. This will be used to (de)serialize requests/responses:

    * `:name` (`t:atom/0`) - Maps the resource attribute name to the given key.

    * `:serialize` (`t:boolean/0`) - Controls wether the attribute is serialized in responses. The default value is `true`.

    * `:deserialize` (`t:boolean/0`) - Controls wether the attribute is deserialized in requests. The default value is `true`.

  The default value is `[]`.

* `:id_attribute` (`t:atom/0`) - Attribute on your data to be used as the JSON:API resource id. The default value is `:id`.

* `:relationships` (`t:keyword/0`) - Resource relationships. This will be used to (de)serialize requests/responses

    * `:name` (`t:atom/0`) - Maps the resource relationship name to the given key.

    * `:many` (`t:boolean/0`) - Specifies a to many relationship. The default value is `false`.

    * `:resource` (`t:atom/0`) - Required. Specifies the resource to be used to serialize the relationship

  The default value is `[]`.

  * `:name` (`t:atom/0`) - Maps the resource relationship name to the given key.

  * `:many` (`t:boolean/0`) - Specifies a to many relationship. The default value is `false`.

  * `:resource` (`t:atom/0`) - Required. Specifies the resource to be used to serialize the relationship

* `:type` (`t:String.t/0`) - Required. Resource type. To be used as the JSON:API resource type value

# `t`

```elixir
@type t() :: struct()
```

Resource module

A struct implementing the `JSONAPIPlug.Resource` protocol

# `attributes`

```elixir
@spec attributes(t()) :: [field_name()]
```

Returns the resource attributes

# `field_option`

```elixir
@spec field_option(t(), field_name(), atom()) :: term()
```

Resource field option

Returns the value of the requested field option

# `id_attribute`

```elixir
@spec id_attribute(t()) :: field_name()
```

Resource Id Attribute

Returns the attribute used to fetch resource ids for resources by the

# `recase_field`

```elixir
@spec recase_field(t(), field_name(), JSONAPIPlug.case()) :: String.t()
```

Resource function to recase fields

Returns the field is the required case

# `relationships`

```elixir
@spec relationships(t()) :: [field_name()]
```

Resource relationships

Returns the keyword list of resource relationships for the

# `type`

```elixir
@spec type(t()) :: JSONAPIPlug.Document.ResourceObject.type()
```

Resource Type

Returns the Resource Type of resources for the

---

*Consult [api-reference.md](api-reference.md) for complete listing*
