Coder Social home page Coder Social logo

graphql_relay's Introduction

GraphQL Elixir

Build Status Public Slack Discussion

An Elixir implementation of Facebook's GraphQL.

This is the core GraphQL query parsing and execution engine whose goal is to be transport, server and datastore agnostic.

In order to setup an HTTP server (ie Phoenix) to handle GraphQL queries you will need plug_graphql. Examples for Phoenix can be found at hello_graphql_phoenix, so look here for a starting point for writing your own schemas.

Other ways of handling queries will be added in due course.

Installation

First, add GraphQL to your mix.exs dependencies:

defp deps do
  [{:graphql, "~> 0.3"}]
end

Add GraphQL to your mix.exs applications:

def application do
  # Add the application to your list of applications.
  # This will ensure that it will be included in a release.
  [applications: [:logger, :graphql]]
end

Then, update your dependencies:

$ mix deps.get

Usage

First setup your schema

defmodule TestSchema do
  def schema do
    %GraphQL.Schema{
      query: %GraphQL.Type.ObjectType{
        name: "RootQueryType",
        fields: %{
          greeting: %{
            type: %GraphQL.Type.String{},
            resolve: &TestSchema.greeting/3,
            description: "Greeting",
            args: %{
              name: %{type: %GraphQL.Type.String{}, description: "The name of who you'd like to greet."},
            }
          }
        }
      }
    }
  end

  def greeting(_, %{name: name}, _), do: "Hello, #{name}!"
  def greeting(_, _, _), do: "Hello, world!"
end

Execute a simple GraphQL query

iex> GraphQL.execute(TestSchema.schema, "{greeting}")
{:ok, %{data: %{"greeting" => "Hello, world!"}}}

Status

This is a work in progress, right now here's what is done:

  • Parser for GraphQL (including Type definitions)
  • AST matching the graphql-js types as closely as possible
  • Schema definition
  • Query execution
    • Scalar types
    • Arguments
    • Multiple forms of resolution
    • Complex types (List, Object, etc)
    • Fragments in queries
    • Extract variable values
  • Introspection
  • [WIP] Query validation
  • Directives

Resources

Implementation

Tokenisation is done with leex and parsing with yecc. Both very useful Erlang tools for parsing. Yecc in particular is used by Elixir itself.

Some resources on using leex and yecc:

The Execution logic follows the GraphQL JS Reference Implementation pretty closely, as does the module structure of the project. Not to mention the naming of files and concepts.

If you spot anything that isn't following Elixir conventions though, that's a mistake. Please let us know by opening an issue or a PR and we'll fix it.

Developers

Getting Started

Clone the repo and fetch its dependencies:

$ git clone https://github.com/graphql-elixir/graphql.git
$ cd graphql
$ mix deps.get
$ mix test

Atom Editor Support

Using the language-erlang package? .xrl and .yrl files not syntax highlighting?

Syntax highlighting in Atom for leex (.xrl) and yecc (yrl) can be added by modifying grammars/erlang.cson.

Just open the atom-language-erlang package code in Atom and make the change described here:

jonathanmarvens/atom-language-erlang#11

however if that PR has been merged then just grab the latest version of the plugin!

Contributing

We actively welcome pull requests, bug reports, feedback, issues, questions. Come and chat in the #erlang channel on Slack

If you're planning to implement anything major, please let us know before you get too far so we can make sure your PR will be as mergable as possible. Oh, and don't forget to write tests.

License

BSD.

graphql_relay's People

Contributors

cgiffard avatar dre1080 avatar seanabrahams avatar thaterikperson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

graphql_relay's Issues

could not find repositories for application :todo.

Getting the following error. What am I missing?

bash-3.2$ mix ecto.create && mix ecto.migrate                                                                                                                                                               
warning: could not find repositories for application :todo.                                                                                                                                                 

You can avoid this warning by passing the -r flag or by setting the                                                                                                                                         
repositories managed by this application in your config/config.exs:                                                                                                                                         

    config :todo, ecto_repos: [...]                                                                                                                                                                         

The configuration may be an empty list if it does not define any repo. 

GraphiQL IDE

More of a question than an issue.

Is there a way to invoke the GraphiQL IDE from a URL (e.g., /graphql/) to run ad hoc queries against the graphql server?

Mutation Input variables are not making it to resolve functions

It looks like graphql-elixir isn't parsing variables properly for Relay mutations. It receives the correct variables to the execute function, but they don't make it to the resolve functions. This may be due to the input: vs "input" (atom vs string) issue.

Fix Elixir 1.3 and other warnings

Some of these will be fixed by graphql-elixir/graphql#89 but there are quite a number of others.

✪ mix test
WARN:  Missing plugins: [pc]
==> esqlite (compile)
Compiled src/esqlite3_nif.erl
Compiled src/esqlite3.erl
Compiling c_src/esqlite3_nif.c
Compiling c_src/queue.c
Compiling c_src/sqlite3.c
c_src/sqlite3.c:9111:26: warning: unused variable 'sqlite3one' [-Wunused-const-variable]
SQLITE_PRIVATE const int sqlite3one = 1;
                         ^
1 warning generated.
==> poolboy (compile)
Compiled src/poolboy_worker.erl
Compiled src/poolboy_sup.erl
Compiled src/poolboy.erl
==> decimal
Compiling 1 file (.ex)
Generated decimal app
==> graphql
Compiling 1 file (.yrl)
Compiling 1 file (.xrl)
Compiling 2 files (.erl)
Compiling 48 files (.ex)
warning: the variable "accumulator" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/lang/ast/type_info_visitor.ex:149

warning: the variable "accumulator" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/lang/ast/type_info_visitor.ex:170

warning: the variable "acc" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/validation/rules/no_fragment_cycles.ex:75

warning: the variable "acc" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/validation/rules/no_fragment_cycles.ex:75

warning: the variable "accumulator" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/validation/rules/fields_on_correct_type.ex:27

warning: the variable "message" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/validation/rules/fields_on_correct_type.ex:91

warning: function GraphQL.Lang.AST.TypeInfo.nullable_type/2 is undefined or private
  lib/graphql/lang/ast/type_info_visitor.ex:126

Generated graphql app
==> poison
Compiling 4 files (.ex)
Generated poison app
==> pipe
Compiling 1 file (.ex)
Generated pipe app
==> ecto
Compiling 73 files (.ex)
warning: function Ecto.Pools.Poolboy.Worker.behaviour_info/1 is undefined or private
  lib/ecto/pools/poolboy/worker.ex:5

warning: function Ecto.Adapters.MySQL.Connection.all/1 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:85

warning: function Ecto.Adapters.MySQL.Connection.delete/4 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:85

warning: function Ecto.Adapters.MySQL.Connection.delete_all/1 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:85

warning: function Ecto.Adapters.MySQL.Connection.execute_ddl/1 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:85

warning: function Ecto.Adapters.MySQL.Connection.update/5 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:85

warning: function Ecto.Adapters.MySQL.Connection.update_all/1 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:85

warning: function Ecto.Adapters.MySQL.Connection.insert/4 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
Found at 2 locations:
  lib/ecto/adapters/mysql.ex:85
  lib/ecto/adapters/mysql.ex:172

warning: function Ecto.Adapters.MySQL.Connection.to_constraints/1 is undefined (module Ecto.Adapters.MySQL.Connection is not available)
  lib/ecto/adapters/mysql.ex:177

warning: function :sbroker.async_ask_r/3 is undefined (module :sbroker is not available)
Found at 2 locations:
  lib/ecto/pools/sojourn_broker/worker.ex:192
  lib/ecto/pools/sojourn_broker/worker.ex:198

warning: function :sbroker.cancel/3 is undefined (module :sbroker is not available)
  lib/ecto/pools/sojourn_broker/worker.ex:260

warning: function :sbroker.await/2 is undefined (module :sbroker is not available)
  lib/ecto/pools/sojourn_broker/worker.ex:261

warning: function :sbroker.ask/2 is undefined (module :sbroker is not available)
  lib/ecto/pools/sojourn_broker.ex:75

warning: function Ecto.Adapters.Postgres.Connection.all/1 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

warning: function Ecto.Adapters.Postgres.Connection.delete/4 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

warning: function Ecto.Adapters.Postgres.Connection.delete_all/1 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

warning: function Ecto.Adapters.Postgres.Connection.execute_ddl/1 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

warning: function Ecto.Adapters.Postgres.Connection.insert/4 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

warning: function Ecto.Adapters.Postgres.Connection.update/5 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

warning: function Ecto.Adapters.Postgres.Connection.update_all/1 is undefined (module Ecto.Adapters.Postgres.Connection is not available)
  lib/ecto/adapters/postgres.ex:56

Generated ecto app
==> sqlitex
Compiling 7 files (.ex)
Generated sqlitex app
==> sqlite_ecto
Compiling 7 files (.ex)
warning: the variable "args" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/sqlite_ecto/query.ex:357

warning: the variable "args" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/sqlite_ecto/query.ex:363

Generated sqlite_ecto app
==> graphql_relay
Compiling 6 files (.ex)
warning: the variable "end_offset" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/list.ex:32

warning: the variable "start_offset" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/list.ex:35

warning: the variable "end_offset" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/list.ex:36

warning: the variable "start_offset" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/list.ex:43

warning: the variable "start_offset" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/list.ex:55

warning: the variable "end_offset" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/list.ex:56

warning: the variable "query" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:24

warning: the variable "query" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:33

warning: the variable "query" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:42

warning: the variable "query" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:48

warning: the variable "query" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:54

warning: the variable "query" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:59

warning: the variable "has_prev_page" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:83

warning: the variable "has_next_page" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explicitly return the variable value instead. For example:

    case int do
      1 -> atom = :one
      2 -> atom = :two
    end

should be written as

    atom =
      case int do
        1 -> :one
        2 -> :two
      end

Unsafe variable found at:
  lib/graphql/relay/connection/ecto.ex:84

Generated graphql_relay app
Excluding tags: [:skip]

..................................................................................

Finished in 0.6 seconds
83 tests, 0 failures, 1 skipped

Randomized with seed 341524

Mutation.ex won't compile in Elixir 1.3

It appears Elixir 1.3 doesn't work with the anonymous function in GraphQL.Relay.Mutation.new/1.

== Compilation error on file web/router.ex ==
** (ArgumentError) cannot escape #Function<0.44923427/3 in GraphQL.Relay.Mutation.new/1>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, pids and remote functions in the format &Mod.fun/arity

I confirmed this works in Elixir 1.2.4 and Phoenix 1.1.4.

web/router.ex

#…
scope "/q" do
  forward "/", GraphQL.Plug, schema: {GraphQLTest.Root, :schema}
end
#…

web/graphql/root.ex

defmodule GraphQLTest.Root do

  alias GraphQL.Relay.Mutation

  def schema do
    %GraphQL.Schema{
      query: %GraphQL.Type.ObjectType{
        name: "Query",
        fields: %{
          greeting: %{
            type: %GraphQL.Type.String{},
            resolve: &GraphQLTest.Root.greeting/3,
          },
        }
      },
      mutation: %GraphQL.Type.ObjectType{
        name: "Mutation",
        fields: %{
          addUser: Mutation.new(%{
            name: "addUser",
            input_fields: %{
              name: %{type: %GraphQL.Type.String{}},
            },
            output_fields: %{
              name: %{type: %GraphQL.Type.String{}},
            },
            mutate_and_get_payload: &GraphQLTest.Root.mutate_and_get_payload/2,
          })
        }
      }
    }
  end

  def mutate_and_get_payload(input, info), do: %{name: "Hello #{input["name"]}"}
  def greeting(_, _, _), do: %{name: "Hello world"}
end

I don't have any great ideas for a solution. My current workaround is to include most of the Mutation.ex code directly in my own file so I can avoid the anonymous function. I'm still a bit of an Elixir beginner so would love to learn a true Elixir way to fix this.

Introspect Ecto Connection order field and direction from query

We recently updated the API for Ecto Connections to accept arguments for sorting the connection by adding ordered_by and ordered_by_direction arguments. This works if you want to sort by the Connection's underlying table, but not if you want to sort by a joined table.

Thinking on this it became clear that we can simply look to see if the passed in Ecto query has an order_by clause from which we can then derive the sort field and direction. We don't need separate ordered_by and ordered_by_direction arguments. Just introspect the query.

Upgrading to phoenix 1.2 causes error in node_interface

== Compilation error on file web/router.ex ==
** (ArgumentError) cannot escape #Function<1.97113962/1 in App.PublicSchema.node_interface/0>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, pids and remote functions in the format &Mod.fun/arity
    (elixir) src/elixir_quote.erl:119: :elixir_quote.argument_error/1
    (elixir) src/elixir_quote.erl:246: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:382: :elixir_quote.do_splice/5
    (elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:246: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:382: :elixir_quote.do_splice/5
    (elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:246: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:382: :elixir_quote.do_splice/5
    (elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:246: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:382: :elixir_quote.do_splice/5
    (elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:246: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:382: :elixir_quote.do_splice/5
    (elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:246: :elixir_quote.do_quote/3
    (elixir) src/elixir_quote.erl:382: :elixir_quote.do_splice/5
    (elixir) src/elixir_quote.erl:141: :elixir_quote.escape/2
    (elixir) lib/macro.ex:312: Macro.escape/2

  scope "/graphql" do
    pipe_through :api
    forward "/", GraphQL.Plug, schema: {App.PublicSchema, :schema}
  end
  def node_interface do
    Node.define_interface(fn(obj) ->
      case obj do
        %{start_unix_timestamp: _ } ->
          App.Event.Type
        %{comments: _, full_text: _} ->
          App.Article.Type
        %{members: _} ->
            App.Group.Type
        %{email: _, name: _} ->
          App.User.Type
        %{replys: _} ->
          App.Comments.Type
      end
    end)
  end

TodoMVC Example: Text not loading on page load

Turns out it's likely an issue in graphql-elixir as the same query, with different ordering of fields, returns different results.

First is the failing query, second is the successful query pulled from the React/Relay Chrome Plugin. They are both the same except for different ordering of fields.

query ViewerQueries {
  viewer {
    id,
    ...F8
  }
} 

fragment F0 on Todo {
  id
}

fragment F1 on Todo {
  complete,
  id
} 

fragment F2 on Todo {
  complete,
  id,
  text,
  ...F0,
  ...F1
}

fragment F3 on TodoConnection {
  edges {
    node {
      complete,
      id
    },
    cursor
  },
  pageInfo {
    hasNextPage,
    hasPreviousPage
  }
}

fragment F4 on User {
  id,
  totalCount
} 

fragment F5 on User {
  id,
  completedCount
}

fragment F6 on User {
  completedCount,
  id,
  totalCount
}

fragment F7 on User {
  id,
  ...F5,
  ...F6
}

fragment F8 on User { 
  completedCount,
  _todos2Z9A4r:todos(status:"any",first:2147483647) { 
    edges {
      node {
        id,
        ...F2
      },
      cursor
    },
    pageInfo {
      hasNextPage,
      hasPreviousPage
    },
    ...F3
  },
  totalCount,
  id,
  ...F4,
  ...F7
}
query ViewerQueries {
  viewer {
    ...F8,
    id
  }
}

fragment F0 on Todo {
  id
}

fragment F1 on Todo {
  complete,
  id
}

fragment F2 on Todo {
  ...F0,
  ...F1,
  complete,
  id,
  text
}

fragment F3 on TodoConnection {
  edges {
    cursor,
    node {
      complete,
      id
    }
  },
  pageInfo {
    hasNextPage,
    hasPreviousPage
  }
}

fragment F4 on User {
  id,
  totalCount
}

fragment F5 on User {
  completedCount,
  id
}

fragment F6 on User {
  completedCount,
  id,
  totalCount
}

fragment F7 on User {
  ...F5,
  ...F6,
  id
}

fragment F8 on User {
  ...F4,
  ...F7,
  _todos2Z9A4r:todos(status:"any",first:2147483647) {
    ...F3,
    edges {
      cursor,
      node {
        ...F2,
        id
      }
    },
    pageInfo {
      hasNextPage,
      hasPreviousPage
    }
  },
  completedCount,
  id,
  totalCount
}

No such type: `GraphQL.Type.Input`

I currently get the following error:

== Compilation error on file lib/graphql/relay/mutation.ex ==
** (CompileError) lib/graphql/relay/mutation.ex:35: GraphQL.Type.Input.__struct__/0 is undefined, cannot expand struct GraphQL.
Type.Input
    (elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4

could not compile dependency :graphql_relay, "mix compile" failed. You can recompile this dependency with "mix deps.compile gra
phql_relay", update it with "mix deps.update graphql_relay" or clean it with "mix deps.clean graphql_relay"

Docs on how to setup Phoenix app to reload schema.json file whenever schema related file changes

It should be possible to watch the dir(s) that contain your GraphQL schema files and have a change trigger the recreation of the schema.json file automatically. Right now you can manually generate a schema.json file by running: mix run GraphQL.Relay.generate_schema_json from your Phoenix project's root directory (after you've setup some config vars).

I was hoping to find a Phoenix configuration where you can define a function to be run whenever a local file has changed. I have yet to dive into Phoenix's reloading functionality, but am aware of phoenix_live_reload's use of :fs.subscribe().

Unknown plugin "babel-plugin-babel-relay-plugin-loader" specified

I get the following error when starting the example app included in this repo. I looked in the brunch-config.js and other js files, but couldn't find where it specifies the plugin location as the error message suggests.

Unknown plugin "todo/node_modules/babel-plugin-babel-relay-plugin-loader" specified in "base" at 0, attempted to resolve relative to "web/static/js".

Can you please take a look?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.