Skip to content

themusicman/silhouette

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Silhouette (Alpha)

An Elixir Graphql Client

Installation

If available in Hex, the package can be installed by adding silhouette to your list of dependencies in mix.exs:

def deps do
  [
    {:silhouette, "~> 0.1.0"}
  ]
end

Goals

  • Composable
  • Possibly code generation based on Graphql introspection
  • Support Subscriptions (hopefully)
  • Support for changsets (maybe just Ecto changsets)
  • Support for Fragments and Unions

Examples

See the examples directory for examples of how to use this package. Feel free to submit a pull request adding more of them. :)

Potential API Design:

defmodule Graphql.Scalar.Custom do
  @callback to(value :: any()) :: {:ok, binary()} | {:error, atom()}
  @callback from(value :: any()) :: {:ok, any()} | {:error, atom()}
end

defmodule Graphql.Scalar.Custom.DateTime do
  @behaviour Graphql.Scalar.Custom

  def to(value) do
    {:ok, DateTime.to_string(value)}
  end

  def from(value) do
    case DateTime.to_iso8601(value) do
      {:ok, datetime, _} -> {:ok, datetime}
      {:error, error} -> {:error, error}
    end
  end
end

defmodule PhoneNumber do
  defstruct number: ""
end

defmodule User do
  defstruct first_name: "", last_name: "", phone_numbers: [], created_at: nil

  defmodule UserInput do
    defstruct first_name: "", last_name: ""
  end

  # query User($id: ID!) {
  #    user(id: $id) {
  #        id
  #        firstName
  #        lastName
  #        createdAt
  #        phoneNumbers {
  #            number
  #        }
  #    }
  #  }
  def get(id) do
    phone_numbers_selection =
      SelectionSet.into(%PhoneNumber{})
      |> SelectionSet.with(:number, as: :string)

    user_selection =
      SelectionSet.into(%User{})
      |> SelectionSet.with(:first_name, as: :string)
      |> SelectionSet.with(:last_name, as: :string)
      |> SelectionSet.with(:created_at, as: :datetime)
      |> SelectionSet.with(:phone_numbers, list_of: phone_numbers_selection)

    Graphql.query(for: :user, one_of: user_selection)
    |> Graphql.arguments(%{id: "ID!"})
    |> Graphql.variables(%{id: id})
    |> Graphql.headers(%{"Authorization" => "Bearer tokenhere")
    |> Graphql.url("https://example.com/graphql")
  end

  # mutation CreateUser($user: UserInput!) {
  #    createUser(user: $user) {
  #      result {
  #        id
  #        firstName
  #        lastName
  #      }
  #      messages {
  #        message
  #      }
  #    }
  #  }
  def create(attrs) do
    user_selection =
      SelectionSet.into(%User{})
      |> SelectionSet.with(:id)
      |> SelectionSet.with(:first_name)
      |> SelectionSet.with(:last_name)

    messages_selection =
      SelectionSet.into([])
      |> SelectionSet.with(:message)

    result_selection =
      SelectionSet.into(%{result: nil, messages: []})
      |> SelectionSet.with(:result, as: user_selection)
      |> SelectionSet.with(:messages, as: messages_selection)

    Graphql.mutation(:createUser, result_selection)
    |> Graphql.arguments(%{user: "UserInput!"})
    |> Graphql.variables(attrs)
  end
end

User.create(%{user: %{first_name: "Thomas", last_name: "Brewer"}})
|> Graphql.execute()
|> case do
  {:ok, user} -> IO.inspect(user)
  {:error, msg} -> IO.inspect(msg)
end

User.get(1)
|> Graphql.execute()
|> case do
  {:ok, user} -> IO.inspect(user)
  {:error, msg} -> IO.inspect(msg)
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/silhouette.

About

An Elixir Graphql Client

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages