# `JSONAPI.QueryParser`
[🔗](https://github.com/beam-community/jsonapi/blob/main/lib/jsonapi/plugs/query_parser.ex#L1)

Implements a fully JSONAPI V1 spec for parsing a complex query string via the
`query_params` field from a `Plug.Conn` struct and returning Elixir datastructures.
The purpose is to validate and encode incoming queries and fail quickly.

Primarialy this handles:
  * [sorts](http://jsonapi.org/format/#fetching-sorting)
  * [include](http://jsonapi.org/format/#fetching-includes)
  * [filtering](http://jsonapi.org/format/#fetching-filtering)
  * [sparse fieldsets](https://jsonapi.org/format/#fetching-sparse-fieldsets)
  * [pagination](http://jsonapi.org/format/#fetching-pagination)

This Plug works in conjunction with a `JSONAPI.View` as well as some Plug
defined configuration.

In your controller you may add:

```
plug JSONAPI.QueryParser,
  filter: ~w(title),
  sort: ~w(created_at title),
  include: ~w(others) # optionally specify a list of allowed includes.
  view: MyView
```

If you specify which includes are allowed, any include name not in the list
will produce an error. If you omit the `include` list then all relationships
specified by the given resource will be allowed.

If your controller's index function receives a query with params inside those
bounds it will build a `JSONAPI.Config` that has all the validated and parsed
fields for your usage. The final configuration will be added to assigns
`jsonapi_query`.

The final output will be a `JSONAPI.Config` struct and will look similar to the
following:

    %JSONAPI.Config{
      view: MyView,
      opts: [view: MyView, sort: ["created_at", "title"], filter: ["title"]],
      sort: [desc: :created_at] # Easily insertable into an ecto order_by,
      filter: [title: "my title"] # Easily reduceable into ecto where clauses
      include: [comments: :user] # Easily insertable into a Repo.preload,
      fields: %{"myview" => [:id, :text], "comment" => [:id, :body],
      page: %{
        limit: limit,
        offset: offset,
        page: page,
        size: size,
        cursor: cursor
      }}
    }

The final result should allow you to build a query quickly and with little overhead.

## Sparse Fieldsets

Sparse fieldsets are supported. By default your response will include all
available fields. Note that the query to your database is left to you. Should
you want to query your DB for specific fields `JSONAPI.Config.fields` will
return the requested fields for each resource (see above example).

## Options
  * `:view` - The JSONAPI View which is the basis for this plug.
  * `:sort` - List of atoms which define which fields can be sorted on.
  * `:filter` - List of atoms which define which fields can be filtered on.

## Dasherized Fields

Note that if your API is returning dasherized fields (e.g. `"dog-breed": "Corgi"`)
we recommend that you include the `JSONAPI.UnderscoreParameters` Plug in your
API's pipeline with the `replace_query_params` option set to `true`. This will
underscore fields for easier operations in your code.

For more details please see `JSONAPI.UnderscoreParameters`.

# `build_sort`

# `get_valid_fields_for_type`

```elixir
@spec get_valid_fields_for_type(JSONAPI.Config.t(), String.t()) :: [atom()]
```

# `get_view_for_type`

```elixir
@spec get_view_for_type(module(), String.t()) :: module() | no_return()
```

# `handle_include`

# `handle_nested_include`

```elixir
@spec handle_nested_include(
  key :: String.t(),
  valid_include :: list(),
  config :: JSONAPI.Config.t()
) ::
  list() | no_return()
```

# `parse_fields`

```elixir
@spec parse_fields(JSONAPI.Config.t(), map()) :: JSONAPI.Config.t() | no_return()
```

# `parse_filter`

```elixir
@spec parse_filter(
  JSONAPI.Config.t(),
  keyword()
) :: JSONAPI.Config.t()
```

# `parse_include`

# `parse_pagination`

# `parse_sort`

---

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