README.md

<p align="center"><img src="assets/horizontal.png" alt="neuron" height="150px"></p>

[![Build Status](https://github.com/uesteibar/neuron/actions/workflows/ci.yml/badge.svg)](https://github.com/uesteibar/neuron/actions/workflows/ci.yml)
[![Hex Version](https://img.shields.io/hexpm/v/neuron.svg)](https://hex.pm/packages/neuron)

A GraphQL client for Elixir.

## Index

- [Installation](#installation)
- [Usage](#usage)
- [Running Locally](#running-locally)
- [Contributing](#contributing)

## Installation

```elixir
def deps do
  [
    {:neuron, "~> 5.1.0"}
  ]
end
```

## JSON library

Neuron defaults to using Jason for JSON encoding and decoding. To use Jason, add it to your deps:

```elixir
{:jason, "~> 1.1"}
```

It is also possible to customize which JSON library that is used:

```elixir
Neuron.Config.set(json_library: AnotherJSONLibrary)
```

## Connection

Neuron defaults to using HTTP(S) protocol with HTTPoison for Connecting to GraphQL endpoint. You can however customize that behaviour, by providing custom library, which should implement Neuron.Connection behaviour:

```elixir
defmodule MyConnection do
  @behaviour Neuron.Connection

  @impl Neuron.Connection
  def call(body, options) do
    IO.inspect("NEURON CALLED")
    Neuron.Connection.Http.call(body, options)
  end
end
```

Then set it up in config:

```elixir
Neuron.Config.set(connection_module: MyConnection)
```

## Usage

```elixir
iex> Neuron.Config.set(url: "https://example.com/graph")

iex> Neuron.query("""
      {
        films {
          count
        }
      }
    """)
```

Response will be:

```elixir
{:ok, %Neuron.Response{body: %{"data" => %{"films" => %{ "count": 123 }}}, status_code: 200, headers: []}}
```

You can also run mutations:

```elixir
iex> Neuron.query("""
      mutation createUser($name: String!) {
        createUser(name: $name) {
          id
          name
        }
      }
    """,
    %{name: "uesteibar"}
    )
```

You can also set url and headers as shown below:

```elixir
iex> Neuron.query("""
      mutation createUser($name: String!) {
        createUser(name: $name) {
          id
          name
        }
      }
    """,
    %{name: "uesteibar"},
    url: "https://example.com/graph",
    headers: [authorization: "Bearer <token>"]
    )
```

### Overriding HTTP Timeout
`HTTPoison` default timeout is 5000ms, in case we need to handle longer timeout, using default `Neuron.Connection` module, we could set `connection_opts` which will be passed to `HTTPoison`. So to override timeout to 15000ms, we could do:

```elixir
iex> Neuron.Config.set(url: "https://example.com/graph", connection_opts: [recv_timeout: 15_000])

iex> Neuron.query("""
      {
        films {
          count
        }
      }
    """)
```

We can also set the timeout for a single request by passing the `connection_opts` to `Neuron.query/3` instead:

```elixir
iex> Neuron.query("...", %{}, connection_opts: [recv_timeout: 15_000])
```

More extensive documentation can be found at [https://hexdocs.pm/neuron](https://hexdocs.pm/neuron).

## Running locally

Clone the repository:

```bash
git clone git@github.com:uesteibar/neuron.git
```

Install dependencies:

```bash
cd neuron
mix deps.get
```

To run the tests:

```bash
mix test
```

## Style guide

Code is formatted with `mix format` and `mix credo` should not show warnings.

To format the code and run static code analysis with credo

```elixir
mix format
mix credo
```

## Contributing

Pull requests are always welcome =)

The project uses [standard-changelog](https://github.com/conventional-changelog/conventional-changelog) to update the [Changelog](https://github.com/uesteibar/neuron/blob/master/CHANGELOG.md) with each commit message and upgrade the package version.
For that reason every contribution should have a title and body that follows the [conventional commits standard](https://conventionalcommits.org/) conventions (e.g. `feat(connection): Make it smarter than Jarvis`).

To make this process easier, you can do the following:

Install `commitizen` and `cz-conventional-changelog` globally:

```bash
npm i -g commitizen cz-conventional-changelog
```

Save `cz-conventional-changelog` as default:

```bash
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
```

Instead of `git commit`, you can now run:

```
git cz
```

and follow the instructions to generate the commit message.

## Copyright and License

Copyright (c) 2017 Unai Esteibar

This software is released under the [Internet Systems Consortium License](./LICENSE.md).