├── README.md
├── elixir
├── README.md
└── phoenix_graphql
│ ├── .gitignore
│ ├── README.md
│ ├── config
│ ├── config.exs
│ ├── dev.exs
│ ├── prod.exs
│ └── test.exs
│ ├── lib
│ ├── phoenix_graphql.ex
│ └── phoenix_graphql
│ │ ├── endpoint.ex
│ │ └── repo.ex
│ ├── mix.exs
│ ├── mix.lock
│ ├── priv
│ ├── gettext
│ │ ├── en
│ │ │ └── LC_MESSAGES
│ │ │ │ └── errors.po
│ │ └── errors.pot
│ ├── repo
│ │ ├── migrations
│ │ │ ├── 20160526044431_create_user.exs
│ │ │ ├── 20160526044445_create_post.exs
│ │ │ └── 20160526044513_create_comment.exs
│ │ └── seeds.exs
│ └── static
│ │ ├── css
│ │ └── app.css
│ │ ├── favicon.ico
│ │ ├── images
│ │ └── phoenix.png
│ │ ├── js
│ │ ├── app.js
│ │ └── phoenix.js
│ │ └── robots.txt
│ ├── test
│ ├── models
│ │ ├── comment_test.exs
│ │ ├── post_test.exs
│ │ └── user_test.exs
│ ├── support
│ │ ├── channel_case.ex
│ │ ├── conn_case.ex
│ │ └── model_case.ex
│ ├── test_helper.exs
│ └── views
│ │ └── error_view_test.exs
│ └── web
│ ├── api
│ ├── resolver.ex
│ ├── schema.ex
│ └── types
│ │ ├── comment.ex
│ │ ├── post.ex
│ │ └── user.ex
│ ├── channels
│ └── user_socket.ex
│ ├── context.ex
│ ├── controllers
│ └── page_controller.ex
│ ├── gettext.ex
│ ├── models
│ ├── comment.ex
│ ├── post.ex
│ └── user.ex
│ ├── router.ex
│ ├── templates
│ ├── layout
│ │ └── app.html.eex
│ └── page
│ │ └── graphiql.html.eex
│ ├── views
│ ├── error_helpers.ex
│ ├── error_view.ex
│ ├── layout_view.ex
│ └── page_view.ex
│ └── web.ex
├── javascript
├── README.md
├── express_graphql
│ ├── .babelrc
│ ├── .gitignore
│ ├── README.md
│ ├── api
│ │ ├── schema.js
│ │ └── types
│ │ │ ├── commentType.js
│ │ │ ├── postType.js
│ │ │ └── userType.js
│ ├── app.js
│ ├── bin
│ │ └── www
│ ├── config
│ │ └── config.json
│ ├── migrations
│ │ ├── 20160521095312-create-user.js
│ │ ├── 20160521095507-create-post.js
│ │ └── 20160521100324-create-comment.js
│ ├── models
│ │ ├── comment.js
│ │ ├── index.js
│ │ ├── post.js
│ │ └── user.js
│ ├── package.json
│ └── seeders
│ │ ├── 20160521103212-user.js
│ │ ├── 20160521111530-post.js
│ │ └── 20160521111557-comment.js
├── koa_graphql
│ ├── .babelrc
│ ├── .editorconfig
│ ├── .gitignore
│ ├── .jshintrc
│ ├── README.md
│ ├── api
│ │ ├── schema.js
│ │ └── types
│ │ │ ├── commentType.js
│ │ │ ├── postType.js
│ │ │ └── userType.js
│ ├── app.js
│ ├── bookshelf.js
│ ├── migrations
│ │ ├── 20160521155821_users.js
│ │ ├── 20160521155829_posts.js
│ │ └── 20160521155833_comments.js
│ ├── models
│ │ ├── comment.js
│ │ ├── post.js
│ │ └── user.js
│ ├── package.json
│ └── seeds
│ │ ├── comments.js
│ │ ├── posts.js
│ │ └── users.js
└── meteor_graphql
│ ├── .gitignore
│ ├── .meteor
│ ├── .finished-upgraders
│ ├── .gitignore
│ ├── .id
│ ├── packages
│ ├── platforms
│ ├── release
│ └── versions
│ ├── README.md
│ ├── client
│ └── main.html
│ ├── imports
│ ├── api
│ │ └── schema.js
│ └── collections
│ │ ├── comments.js
│ │ ├── posts.js
│ │ ├── schemas.js
│ │ └── users.js
│ ├── package.json
│ └── server
│ ├── fixtures
│ └── users.js
│ ├── main.js
│ ├── publications
│ └── posts.js
│ └── seeds.js
├── php
├── README.md
└── laravel_graphql
│ ├── .gitattributes
│ ├── .gitignore
│ ├── app
│ ├── Comment.php
│ ├── Console
│ │ ├── Commands
│ │ │ └── Inspire.php
│ │ └── Kernel.php
│ ├── Events
│ │ └── Event.php
│ ├── Exceptions
│ │ └── Handler.php
│ ├── GraphQL
│ │ ├── Query
│ │ │ ├── CommentsQuery.php
│ │ │ ├── PostQuery.php
│ │ │ ├── PostsQuery.php
│ │ │ ├── UserQuery.php
│ │ │ └── UsersQuery.php
│ │ ├── Type
│ │ │ ├── CommentType.php
│ │ │ ├── PostType.php
│ │ │ └── UserType.php
│ │ └── mutation
│ │ │ └── UpdateUserPasswordMutation.php
│ ├── Http
│ │ ├── Controllers
│ │ │ ├── Auth
│ │ │ │ ├── AuthController.php
│ │ │ │ └── PasswordController.php
│ │ │ ├── Controller.php
│ │ │ └── PagesController.php
│ │ ├── Kernel.php
│ │ ├── Middleware
│ │ │ ├── Authenticate.php
│ │ │ ├── EncryptCookies.php
│ │ │ ├── RedirectIfAuthenticated.php
│ │ │ └── VerifyCsrfToken.php
│ │ ├── Requests
│ │ │ └── Request.php
│ │ └── routes.php
│ ├── Jobs
│ │ └── Job.php
│ ├── Listeners
│ │ └── .gitkeep
│ ├── Policies
│ │ └── .gitkeep
│ ├── Post.php
│ ├── Providers
│ │ ├── AppServiceProvider.php
│ │ ├── AuthServiceProvider.php
│ │ ├── EventServiceProvider.php
│ │ └── RouteServiceProvider.php
│ └── User.php
│ ├── artisan
│ ├── bootstrap
│ ├── app.php
│ ├── autoload.php
│ └── cache
│ │ └── .gitignore
│ ├── composer.json
│ ├── composer.lock
│ ├── config
│ ├── app.php
│ ├── auth.php
│ ├── broadcasting.php
│ ├── cache.php
│ ├── compile.php
│ ├── database.php
│ ├── filesystems.php
│ ├── graphql.php
│ ├── jwt.php
│ ├── mail.php
│ ├── queue.php
│ ├── services.php
│ ├── session.php
│ └── view.php
│ ├── database
│ ├── .gitignore
│ ├── factories
│ │ └── ModelFactory.php
│ ├── migrations
│ │ ├── .gitkeep
│ │ ├── 2014_10_12_000000_create_users_table.php
│ │ ├── 2014_10_12_100000_create_password_resets_table.php
│ │ ├── 2016_05_31_071858_create_posts_table.php
│ │ └── 2016_05_31_071904_create_comments_table.php
│ └── seeds
│ │ ├── .gitkeep
│ │ ├── CommentsTableSeeder.php
│ │ ├── DatabaseSeeder.php
│ │ ├── PostsTableSeeder.php
│ │ └── UsersTableSeeder.php
│ ├── gulpfile.js
│ ├── package.json
│ ├── phpunit.xml
│ ├── public
│ ├── .htaccess
│ ├── favicon.ico
│ ├── index.php
│ ├── robots.txt
│ └── web.config
│ ├── readme.md
│ ├── resources
│ ├── assets
│ │ └── sass
│ │ │ └── app.scss
│ ├── lang
│ │ └── en
│ │ │ ├── auth.php
│ │ │ ├── pagination.php
│ │ │ ├── passwords.php
│ │ │ └── validation.php
│ └── views
│ │ ├── errors
│ │ └── 503.blade.php
│ │ ├── pages
│ │ └── welcome.blade.php
│ │ └── vendor
│ │ └── .gitkeep
│ ├── server.php
│ └── storage
│ ├── app
│ ├── .gitignore
│ └── public
│ │ └── .gitignore
│ ├── framework
│ ├── .gitignore
│ ├── cache
│ │ └── .gitignore
│ ├── sessions
│ │ └── .gitignore
│ └── views
│ │ └── .gitignore
│ └── logs
│ └── .gitignore
├── python
├── README.md
├── django_graphql
│ ├── README.md
│ ├── blog
│ │ ├── __init__.py
│ │ ├── __init__.pyc
│ │ ├── admin.py
│ │ ├── admin.pyc
│ │ ├── apps.py
│ │ ├── fixtures
│ │ │ └── seed.json
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0001_initial.pyc
│ │ │ ├── __init__.py
│ │ │ └── __init__.pyc
│ │ ├── models.py
│ │ ├── models.pyc
│ │ ├── schema.pyc
│ │ ├── tests.py
│ │ ├── urls.py
│ │ ├── urls.pyc
│ │ ├── views.py
│ │ └── views.pyc
│ ├── db.sqlite3
│ ├── django_graphql
│ │ ├── __init__.py
│ │ ├── __init__.pyc
│ │ ├── schema.py
│ │ ├── schema.pyc
│ │ ├── settings.py
│ │ ├── settings.pyc
│ │ ├── urls.py
│ │ ├── urls.pyc
│ │ ├── wsgi.py
│ │ └── wsgi.pyc
│ ├── manage.py
│ └── requirements.txt
└── flask_graphql
│ ├── README.md
│ ├── __init__.py
│ ├── app.py
│ ├── app.pyc
│ ├── config.py
│ ├── config.pyc
│ ├── manage.py
│ ├── migrations
│ ├── README
│ ├── alembic.ini
│ ├── env.py
│ ├── env.pyc
│ ├── script.py.mako
│ └── versions
│ │ ├── 11261ac968e5_.py
│ │ └── 11261ac968e5_.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── requirements.txt
│ ├── schema.py
│ ├── schema.pyc
│ └── seed.py
├── ruby
├── README.md
├── cuba_grapgql
│ ├── .bundle
│ │ └── config
│ ├── .gitignore
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── api
│ │ ├── database.rb
│ │ ├── schema.rb
│ │ └── types
│ │ │ ├── comment_type.rb
│ │ │ ├── post_type.rb
│ │ │ └── user_type.rb
│ ├── config.ru
│ ├── cuba_grapgql.rb
│ ├── middlewares
│ │ └── pass_auth_token.rb
│ └── views
│ │ ├── graphiql.erb
│ │ └── layout.erb
├── rails_graphql
│ ├── .gitignore
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── Rakefile
│ ├── app
│ │ ├── api
│ │ │ ├── node_identification.rb
│ │ │ ├── schema.rb
│ │ │ └── types
│ │ │ │ ├── comment_type.rb
│ │ │ │ ├── post_type.rb
│ │ │ │ └── user_type.rb
│ │ ├── controllers
│ │ │ ├── application_controller.rb
│ │ │ ├── concerns
│ │ │ │ └── .keep
│ │ │ └── graphql_controller.rb
│ │ ├── models
│ │ │ ├── application_record.rb
│ │ │ ├── comment.rb
│ │ │ ├── concerns
│ │ │ │ └── .keep
│ │ │ ├── post.rb
│ │ │ └── user.rb
│ │ └── views
│ │ │ └── graphiql
│ │ │ └── rails
│ │ │ └── editors
│ │ │ └── show.html.erb
│ ├── bin
│ │ ├── bundle
│ │ ├── rails
│ │ ├── rake
│ │ ├── setup
│ │ ├── spring
│ │ └── update
│ ├── config.ru
│ ├── config
│ │ ├── application.rb
│ │ ├── boot.rb
│ │ ├── database.yml
│ │ ├── environment.rb
│ │ ├── environments
│ │ │ ├── development.rb
│ │ │ ├── production.rb
│ │ │ └── test.rb
│ │ ├── initializers
│ │ │ ├── active_record_belongs_to_required_by_default.rb
│ │ │ ├── application_controller_renderer.rb
│ │ │ ├── backtrace_silencers.rb
│ │ │ ├── callback_terminator.rb
│ │ │ ├── cookies_serializer.rb
│ │ │ ├── filter_parameter_logging.rb
│ │ │ ├── graphiql.rb
│ │ │ ├── inflections.rb
│ │ │ ├── mime_types.rb
│ │ │ ├── per_form_csrf_tokens.rb
│ │ │ ├── request_forgery_protection.rb
│ │ │ ├── session_store.rb
│ │ │ ├── ssl_options.rb
│ │ │ ├── to_time_preserves_timezone.rb
│ │ │ └── wrap_parameters.rb
│ │ ├── locales
│ │ │ └── en.yml
│ │ ├── puma.rb
│ │ ├── routes.rb
│ │ ├── secrets.yml
│ │ └── spring.rb
│ ├── db
│ │ ├── migrate
│ │ │ ├── 20160524121108_create_users.rb
│ │ │ ├── 20160524121211_create_posts.rb
│ │ │ └── 20160524121235_create_comments.rb
│ │ ├── schema.rb
│ │ ├── seeds.rb
│ │ └── structure.sql
│ ├── lib
│ │ ├── assets
│ │ │ └── .keep
│ │ ├── pass_auth_token.rb
│ │ └── tasks
│ │ │ └── .keep
│ ├── log
│ │ └── .keep
│ ├── public
│ │ ├── 404.html
│ │ ├── 422.html
│ │ ├── 500.html
│ │ ├── apple-touch-icon-precomposed.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon.ico
│ │ └── robots.txt
│ └── tmp
│ │ └── .keep
├── roda_graphql
│ ├── .env
│ ├── .gitignore
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── Rakefile
│ ├── api
│ │ ├── models
│ │ │ ├── comment.rb
│ │ │ ├── post.rb
│ │ │ └── user.rb
│ │ ├── routes
│ │ │ └── main.rb
│ │ ├── schema.rb
│ │ └── types
│ │ │ ├── comment_type.rb
│ │ │ ├── post_type.rb
│ │ │ └── user_type.rb
│ ├── assets
│ │ ├── assets.rb
│ │ ├── css
│ │ │ ├── application.css
│ │ │ ├── graphiql-0.7.0.css
│ │ │ └── main.css
│ │ └── js
│ │ │ ├── application.js
│ │ │ ├── fetch-0.10.1.js
│ │ │ ├── graphiql-0.7.0.js
│ │ │ ├── react-15.0.1.js
│ │ │ └── react-dom-15.0.1.js
│ ├── blog.db
│ ├── config.ru
│ ├── db
│ │ ├── migrate
│ │ │ ├── 1_user.rb
│ │ │ ├── 2_post.rb
│ │ │ └── 3_comment.rb
│ │ └── seeds
│ │ │ └── 20150928000000_seed.rb
│ ├── middlewares
│ │ └── pass_auth_token.rb
│ ├── roda_graphql.rb
│ └── views
│ │ ├── graphiql.erb
│ │ └── layout.erb
└── sinatra_graphql
│ ├── .gitignore
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── Rakefile
│ ├── config.ru
│ ├── config
│ ├── db.yml
│ └── initializers
│ │ └── database.rb
│ ├── db
│ ├── migrate
│ │ ├── 1_user.rb
│ │ ├── 2_post.rb
│ │ └── 3_comment.rb
│ └── seeds
│ │ └── 20150928000000_seed.rb
│ ├── lib
│ ├── .gitkeep
│ ├── api
│ │ ├── node_identification.rb
│ │ ├── schema.rb
│ │ └── types
│ │ │ ├── comment_type.rb
│ │ │ ├── post_type.rb
│ │ │ └── user_type.rb
│ └── models
│ │ ├── comment.rb
│ │ ├── post.rb
│ │ └── user.rb
│ ├── logs
│ ├── common.log
│ └── output.log
│ ├── middlewares
│ └── pass_auth_token.rb
│ ├── public
│ ├── favicon.ico
│ ├── images
│ │ ├── .gitkeep
│ │ ├── hazel_icon.png
│ │ └── hazel_small.png
│ ├── javascripts
│ │ ├── .gitkeep
│ │ ├── application.js
│ │ ├── fetch-0.10.1.js
│ │ ├── graphiql-0.7.0.js
│ │ ├── react-15.0.1.js
│ │ └── react-dom-15.0.1.js
│ └── stylesheets
│ │ ├── application.css
│ │ ├── graphiql-0.7.0.css
│ │ └── main.css
│ ├── sinatra_graphql.rb
│ └── views
│ ├── graphiql.erb
│ └── layout.erb
└── scala
├── README.md
└── play_grapgql
├── .gitignore
├── LICENSE
├── README
├── app
├── Filters.scala
├── Module.scala
├── controllers
│ ├── AsyncController.scala
│ ├── CountController.scala
│ └── HomeController.scala
├── filters
│ └── ExampleFilter.scala
├── services
│ ├── ApplicationTimer.scala
│ └── Counter.scala
└── views
│ ├── index.scala.html
│ └── main.scala.html
├── bin
└── activator
├── build.sbt
├── conf
├── application.conf
├── logback.xml
└── routes
├── libexec
└── activator-launch-1.3.10.jar
├── project
├── build.properties
└── plugins.sbt
├── public
├── images
│ └── favicon.png
├── javascripts
│ └── hello.js
└── stylesheets
│ └── main.css
└── test
├── ApplicationSpec.scala
└── IntegrationSpec.scala
/elixir/README.md:
--------------------------------------------------------------------------------
1 | # Elixir based web frameworks
2 |
3 | A set of GraphQL server implementation on popular Elixir web frameworks.
4 |
5 | ## Frameworks
6 | * Phoenix
7 |
8 | ```bash
9 | $ brew update
10 | $ brew install elixir
11 | ```
12 |
13 | Then, follow the example readme to setup application locally.
14 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | # App artifacts
2 | /_build
3 | /db
4 | /deps
5 | /*.ez
6 |
7 | # Generate on crash by the VM
8 | erl_crash.dump
9 |
10 | # The config/prod.secret.exs file by default contains sensitive
11 | # data and you should not commit it into version control.
12 | #
13 | # Alternatively, you may comment the line below and commit the
14 | # secrets file as long as you replace its contents by environment
15 | # variables.
16 | /config/prod.secret.exs
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/config/config.exs:
--------------------------------------------------------------------------------
1 | # This file is responsible for configuring your application
2 | # and its dependencies with the aid of the Mix.Config module.
3 | #
4 | # This configuration file is loaded before any dependency and
5 | # is restricted to this project.
6 | use Mix.Config
7 |
8 | # General application configuration
9 | config :phoenix_graphql,
10 | ecto_repos: [PhoenixGraphql.Repo]
11 |
12 | # Configures the endpoint
13 | config :phoenix_graphql, PhoenixGraphql.Endpoint,
14 | url: [host: "localhost"],
15 | secret_key_base: "guMYRuYOMq+olmZ4Vu6xBST4H/MfWRCQDyar85vGraQsw6rSKAHkqgSgTDTOO2zz",
16 | render_errors: [view: PhoenixGraphql.ErrorView, accepts: ~w(json)],
17 | pubsub: [name: PhoenixGraphql.PubSub,
18 | adapter: Phoenix.PubSub.PG2]
19 |
20 | # Configures Elixir's Logger
21 | config :logger, :console,
22 | format: "$time $metadata[$level] $message\n",
23 | metadata: [:request_id]
24 |
25 | # Import environment specific config. This must remain at the bottom
26 | # of this file so it overrides the configuration defined above.
27 | import_config "#{Mix.env}.exs"
28 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/config/dev.exs:
--------------------------------------------------------------------------------
1 | use Mix.Config
2 |
3 | # For development, we disable any cache and enable
4 | # debugging and code reloading.
5 | #
6 | # The watchers configuration can be used to run external
7 | # watchers to your application. For example, we use it
8 | # with brunch.io to recompile .js and .css sources.
9 | config :phoenix_graphql, PhoenixGraphql.Endpoint,
10 | http: [port: 4000],
11 | debug_errors: true,
12 | code_reloader: true,
13 | check_origin: false,
14 | watchers: []
15 |
16 |
17 | # Do not include metadata nor timestamps in development logs
18 | config :logger, :console, format: "[$level] $message\n"
19 |
20 | # Set a higher stacktrace during development. Avoid configuring such
21 | # in production as building large stacktraces may be expensive.
22 | config :phoenix, :stacktrace_depth, 20
23 |
24 | # Configure your database
25 | config :phoenix_graphql, PhoenixGraphql.Repo,
26 | adapter: Ecto.Adapters.Postgres,
27 | username: "gaurav",
28 | database: "phoenix_graphql_dev",
29 | hostname: "localhost",
30 | pool_size: 10
31 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/config/test.exs:
--------------------------------------------------------------------------------
1 | use Mix.Config
2 |
3 | # We don't run a server during test. If one is required,
4 | # you can enable the server option below.
5 | config :phoenix_graphql, PhoenixGraphql.Endpoint,
6 | http: [port: 4001],
7 | server: false
8 |
9 | # Print only warnings and errors during test
10 | config :logger, level: :warn
11 |
12 | # Configure your database
13 | config :phoenix_graphql, PhoenixGraphql.Repo,
14 | adapter: Ecto.Adapters.Postgres,
15 | username: "postgres",
16 | password: "postgres",
17 | database: "phoenix_graphql_test",
18 | hostname: "localhost",
19 | pool: Ecto.Adapters.SQL.Sandbox
20 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/lib/phoenix_graphql.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql do
2 | use Application
3 |
4 | # See http://elixir-lang.org/docs/stable/elixir/Application.html
5 | # for more information on OTP Applications
6 | def start(_type, _args) do
7 | import Supervisor.Spec
8 |
9 | # Define workers and child supervisors to be supervised
10 | children = [
11 | # Start the Ecto repository
12 | supervisor(PhoenixGraphql.Repo, []),
13 | # Start the endpoint when the application starts
14 | supervisor(PhoenixGraphql.Endpoint, []),
15 | # Start your own worker by calling: PhoenixGraphql.Worker.start_link(arg1, arg2, arg3)
16 | # worker(PhoenixGraphql.Worker, [arg1, arg2, arg3]),
17 | ]
18 |
19 | # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
20 | # for other strategies and supported options
21 | opts = [strategy: :one_for_one, name: PhoenixGraphql.Supervisor]
22 | Supervisor.start_link(children, opts)
23 | end
24 |
25 | # Tell Phoenix to update the endpoint configuration
26 | # whenever the application is updated.
27 | def config_change(changed, _new, removed) do
28 | PhoenixGraphql.Endpoint.config_change(changed, removed)
29 | :ok
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/lib/phoenix_graphql/repo.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Repo do
2 | use Ecto.Repo, otp_app: :phoenix_graphql
3 | end
4 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/repo/migrations/20160526044431_create_user.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Repo.Migrations.CreateUser do
2 | use Ecto.Migration
3 |
4 | def change do
5 | create table(:users) do
6 | add :first_name, :string
7 | add :last_name, :string
8 | add :email, :string
9 | add :username, :string
10 |
11 | timestamps
12 | end
13 |
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/repo/migrations/20160526044445_create_post.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Repo.Migrations.CreatePost do
2 | use Ecto.Migration
3 |
4 | def change do
5 | create table(:posts) do
6 | add :title, :string
7 | add :body, :text
8 | add :user_id, references(:users, on_delete: :nothing)
9 |
10 | timestamps
11 | end
12 | create index(:posts, [:user_id])
13 |
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/repo/migrations/20160526044513_create_comment.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Repo.Migrations.CreateComment do
2 | use Ecto.Migration
3 |
4 | def change do
5 | create table(:comments) do
6 | add :body, :text
7 | add :user_id, references(:users, on_delete: :nothing)
8 | add :post_id, references(:posts, on_delete: :nothing)
9 |
10 | timestamps
11 | end
12 | create index(:comments, [:user_id])
13 | create index(:comments, [:post_id])
14 |
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/elixir/phoenix_graphql/priv/static/favicon.ico
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/static/images/phoenix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/elixir/phoenix_graphql/priv/static/images/phoenix.png
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/static/js/app.js:
--------------------------------------------------------------------------------
1 | // for phoenix_html support, including form and button helpers
2 | // copy the following scripts into your javascript bundle:
3 | // * https://raw.githubusercontent.com/phoenixframework/phoenix_html/v2.3.0/priv/static/phoenix_html.js
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/priv/static/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/test/models/comment_test.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.CommentTest do
2 | use PhoenixGraphql.ModelCase
3 |
4 | alias PhoenixGraphql.Comment
5 |
6 | @valid_attrs %{body: "some content"}
7 | @invalid_attrs %{}
8 |
9 | test "changeset with valid attributes" do
10 | changeset = Comment.changeset(%Comment{}, @valid_attrs)
11 | assert changeset.valid?
12 | end
13 |
14 | test "changeset with invalid attributes" do
15 | changeset = Comment.changeset(%Comment{}, @invalid_attrs)
16 | refute changeset.valid?
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/test/models/post_test.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.PostTest do
2 | use PhoenixGraphql.ModelCase
3 |
4 | alias PhoenixGraphql.Post
5 |
6 | @valid_attrs %{body: "some content", title: "some content"}
7 | @invalid_attrs %{}
8 |
9 | test "changeset with valid attributes" do
10 | changeset = Post.changeset(%Post{}, @valid_attrs)
11 | assert changeset.valid?
12 | end
13 |
14 | test "changeset with invalid attributes" do
15 | changeset = Post.changeset(%Post{}, @invalid_attrs)
16 | refute changeset.valid?
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/test/models/user_test.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.UserTest do
2 | use PhoenixGraphql.ModelCase
3 |
4 | alias PhoenixGraphql.User
5 |
6 | @valid_attrs %{email: "some content", first_name: "some content", last_name: "some content", username: "some content"}
7 | @invalid_attrs %{}
8 |
9 | test "changeset with valid attributes" do
10 | changeset = User.changeset(%User{}, @valid_attrs)
11 | assert changeset.valid?
12 | end
13 |
14 | test "changeset with invalid attributes" do
15 | changeset = User.changeset(%User{}, @invalid_attrs)
16 | refute changeset.valid?
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/test/support/channel_case.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.ChannelCase do
2 | @moduledoc """
3 | This module defines the test case to be used by
4 | channel tests.
5 |
6 | Such tests rely on `Phoenix.ChannelTest` and also
7 | import other functionality to make it easier
8 | to build and query models.
9 |
10 | Finally, if the test case interacts with the database,
11 | it cannot be async. For this reason, every test runs
12 | inside a transaction which is reset at the beginning
13 | of the test unless the test case is marked as async.
14 | """
15 |
16 | use ExUnit.CaseTemplate
17 |
18 | using do
19 | quote do
20 | # Import conveniences for testing with channels
21 | use Phoenix.ChannelTest
22 |
23 | alias PhoenixGraphql.Repo
24 | import Ecto
25 | import Ecto.Changeset
26 | import Ecto.Query
27 |
28 |
29 | # The default endpoint for testing
30 | @endpoint PhoenixGraphql.Endpoint
31 | end
32 | end
33 |
34 | setup tags do
35 | :ok = Ecto.Adapters.SQL.Sandbox.checkout(PhoenixGraphql.Repo)
36 |
37 | unless tags[:async] do
38 | Ecto.Adapters.SQL.Sandbox.mode(PhoenixGraphql.Repo, {:shared, self()})
39 | end
40 |
41 | :ok
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/test/test_helper.exs:
--------------------------------------------------------------------------------
1 | ExUnit.start
2 |
3 | Ecto.Adapters.SQL.Sandbox.mode(PhoenixGraphql.Repo, :manual)
4 |
5 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/test/views/error_view_test.exs:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.ErrorViewTest do
2 | use PhoenixGraphql.ConnCase, async: true
3 |
4 | # Bring render/3 and render_to_string/3 for testing custom views
5 | import Phoenix.View
6 |
7 | test "renders 404.json" do
8 | assert render(PhoenixGraphql.ErrorView, "404.json", []) ==
9 | %{errors: %{detail: "Page not found"}}
10 | end
11 |
12 | test "render 500.json" do
13 | assert render(PhoenixGraphql.ErrorView, "500.json", []) ==
14 | %{errors: %{detail: "Internal server error"}}
15 | end
16 |
17 | test "render any other" do
18 | assert render(PhoenixGraphql.ErrorView, "505.json", []) ==
19 | %{errors: %{detail: "Internal server error"}}
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/api/resolver.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Api.Resolver do
2 | alias PhoenixGraphql.Repo
3 |
4 | def find(%{id: id, model: model, preloaders: preloaders}) do
5 | case model |> model.with_comments |> Repo.get!(id) do
6 | nil -> {:error, "No found"}
7 | object -> {:ok, object}
8 | end
9 | end
10 |
11 | def all(%{model: model, preloaders: preloaders}) do
12 | case Repo.all(model) |> Repo.preload(preloaders) do
13 | nil -> {:error, "No #{model} found"}
14 | collection -> {:ok, collection}
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/api/types/comment.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Api.Schema.Types.Comment do
2 | use Absinthe.Schema.Notation
3 |
4 | @desc """
5 | A comment
6 | """
7 | object :comment do
8 | field :id, :id
9 | field :body,
10 | type: :string,
11 | resolve: fn
12 | _, obj ->
13 | {:ok, obj.source.body |> Earmark.to_html}
14 | end
15 | field :inserted_at, :string
16 | field :user, :user
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/api/types/post.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Api.Schema.Types.Post do
2 | use Absinthe.Schema.Notation
3 |
4 | @desc """
5 | A post
6 | """
7 | object :post do
8 | field :id, :id
9 | field :title, :string
10 | field :body,
11 | type: :string,
12 | resolve: fn
13 | _, obj ->
14 | {:ok, obj.source.body |> Earmark.to_html}
15 | end
16 | field :user, :user
17 | field :comments, list_of(:comment)
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/api/types/user.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Api.Schema.Types.User do
2 | use Absinthe.Schema.Notation
3 |
4 | @desc """
5 | A user
6 | """
7 | object :user do
8 | field :id, :id
9 | field :first_name, :string
10 | field :last_name, :string
11 | field :email, :string
12 | field :username, :string
13 | field :posts, list_of(:post)
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/context.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Context do
2 | @moduledoc """
3 | This module is just a regular plug that can look at the conn struct and build
4 | the appropriate absinthe context.
5 | """
6 |
7 | @behaviour Plug
8 |
9 | def init(opts), do: opts
10 | def call(conn, _) do
11 | conn
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/controllers/page_controller.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.PageController do
2 | use PhoenixGraphql.Web, :controller
3 | import Joken
4 |
5 | def graphiql(conn, _params) do
6 | # Pass to root route as we don't know the token
7 | # For real API you would use authentication or something
8 | auth_token = token()
9 | |> with_sub(1234567890)
10 | |> sign(hs256("secret"))
11 | |> get_compact
12 |
13 | render(conn, "graphiql.html", token: auth_token)
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/gettext.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Gettext do
2 | @moduledoc """
3 | A module providing Internationalization with a gettext-based API.
4 |
5 | By using [Gettext](https://hexdocs.pm/gettext),
6 | your module gains a set of macros for translations, for example:
7 |
8 | import PhoenixGraphql.Gettext
9 |
10 | # Simple translation
11 | gettext "Here is the string to translate"
12 |
13 | # Plural translation
14 | ngettext "Here is the string to translate",
15 | "Here are the strings to translate",
16 | 3
17 |
18 | # Domain-based translation
19 | dgettext "errors", "Here is the error message to translate"
20 |
21 | See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage.
22 | """
23 | use Gettext, otp_app: :phoenix_graphql
24 | end
25 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/models/comment.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Comment do
2 | use PhoenixGraphql.Web, :model
3 |
4 | schema "comments" do
5 | field :body, :string
6 | belongs_to :user, PhoenixGraphql.User
7 | belongs_to :post, PhoenixGraphql.Post
8 |
9 | timestamps
10 | end
11 |
12 | @doc """
13 | Builds a changeset based on the `struct` and `params`.
14 | """
15 | def changeset(struct, params \\ %{}) do
16 | struct
17 | |> cast(params, [:body])
18 | |> validate_required([:body])
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/models/post.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Post do
2 | use PhoenixGraphql.Web, :model
3 |
4 | schema "posts" do
5 | field :title, :string
6 | field :body, :string
7 | belongs_to :user, PhoenixGraphql.User
8 |
9 | has_many :comments, PhoenixGraphql.Comment
10 | timestamps
11 | end
12 |
13 | @doc """
14 | Builds a changeset based on the `struct` and `params`.
15 | """
16 | def changeset(struct, params \\ %{}) do
17 | struct
18 | |> cast(params, [:title, :body])
19 | |> validate_required([:title, :body])
20 | end
21 |
22 | def with_comments(query) do
23 | from p in query,
24 | join: c in assoc(p, :comments),
25 | join: u in PhoenixGraphql.User, on: c.user_id == u.id,
26 | order_by: [desc: c.id],
27 | preload: [:user, comments: {c, user: u}]
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/models/user.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.User do
2 | use PhoenixGraphql.Web, :model
3 |
4 | schema "users" do
5 | field :first_name, :string
6 | field :last_name, :string
7 | field :email, :string
8 | field :username, :string
9 |
10 | has_many :comments, PhoenixGraphql.Comment
11 | has_many :posts, PhoenixGraphql.Post
12 |
13 | timestamps
14 | end
15 |
16 | @doc """
17 | Builds a changeset based on the `struct` and `params`.
18 | """
19 | def changeset(struct, params \\ %{}) do
20 | struct
21 | |> cast(params, [:first_name, :last_name, :email, :username])
22 | |> validate_required([:first_name, :last_name, :email, :username])
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/router.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.Router do
2 | use PhoenixGraphql.Web, :router
3 | import Joken
4 |
5 | @skip_token_verification %{joken_skip: true}
6 |
7 | pipeline :browser do
8 | plug :accepts, ["html"]
9 | plug :fetch_session
10 | plug :fetch_flash
11 | plug :protect_from_forgery
12 | plug :put_secure_browser_headers
13 | end
14 |
15 | pipeline :graphql do
16 | plug :accepts, ["json"]
17 | plug :fetch_session
18 | plug :fetch_flash
19 | plug :protect_from_forgery
20 | plug Joken.Plug, verify: &PhoenixGraphql.Router.verify_function/0
21 | plug PhoenixGraphql.Context
22 | end
23 |
24 | # Skip root route
25 | scope "/", PhoenixGraphql do
26 | pipe_through :browser
27 | get "/", PageController, :graphiql, private: @skip_token_verification
28 | end
29 |
30 | scope "/graphql" do
31 | pipe_through :graphql
32 | get "/", Absinthe.Plug, schema: PhoenixGraphql.Api.Schema
33 | post "/", Absinthe.Plug, schema: PhoenixGraphql.Api.Schema
34 | end
35 |
36 | def verify_function() do
37 | %Joken.Token{}
38 | |> with_json_module(Poison)
39 | |> with_signer(hs256("secret"))
40 | |> with_sub(1234567890)
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/templates/layout/app.html.eex:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | <%= render @view_module, @view_template, assigns %>
25 |
26 |
27 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/views/error_helpers.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.ErrorHelpers do
2 | @moduledoc """
3 | Conveniences for translating and building error messages.
4 | """
5 |
6 | @doc """
7 | Translates an error message using gettext.
8 | """
9 | def translate_error({msg, opts}) do
10 | # Because error messages were defined within Ecto, we must
11 | # call the Gettext module passing our Gettext backend. We
12 | # also use the "errors" domain as translations are placed
13 | # in the errors.po file.
14 | # Ecto will pass the :count keyword if the error message is
15 | # meant to be pluralized.
16 | # On your own code and templates, depending on whether you
17 | # need the message to be pluralized or not, this could be
18 | # written simply as:
19 | #
20 | # dngettext "errors", "1 file", "%{count} files", count
21 | # dgettext "errors", "is invalid"
22 | #
23 | if count = opts[:count] do
24 | Gettext.dngettext(PhoenixGraphql.Gettext, "errors", msg, msg, count, opts)
25 | else
26 | Gettext.dgettext(PhoenixGraphql.Gettext, "errors", msg, opts)
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/views/error_view.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.ErrorView do
2 | use PhoenixGraphql.Web, :view
3 |
4 | def render("404.json", _assigns) do
5 | %{errors: %{detail: "Page not found"}}
6 | end
7 |
8 | def render("500.json", _assigns) do
9 | %{errors: %{detail: "Internal server error"}}
10 | end
11 |
12 | # In case no render clause matches or no
13 | # template is found, let's render it as 500
14 | def template_not_found(_template, assigns) do
15 | render "500.json", assigns
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/views/layout_view.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.LayoutView do
2 | use PhoenixGraphql.Web, :view
3 | end
4 |
--------------------------------------------------------------------------------
/elixir/phoenix_graphql/web/views/page_view.ex:
--------------------------------------------------------------------------------
1 | defmodule PhoenixGraphql.PageView do
2 | use PhoenixGraphql.Web, :view
3 | end
4 |
--------------------------------------------------------------------------------
/javascript/README.md:
--------------------------------------------------------------------------------
1 | # Node based web frameworks
2 |
3 | A set of GraphQL server implementation on popular Node web frameworks.
4 |
5 | ## Frameworks
6 | * Express
7 | * Koa
8 | * Meteor
9 |
10 | ```bash
11 | $ brew update
12 | $ brew install node # or download package from https://nodejs.org/en/download/
13 | ```
14 |
15 | Then, follow the example readme to setup application locally.
16 |
--------------------------------------------------------------------------------
/javascript/express_graphql/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-0"]
3 | }
4 |
--------------------------------------------------------------------------------
/javascript/express_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 |
--------------------------------------------------------------------------------
/javascript/express_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Express GraphQL Server
2 |
3 | ## Getting started locally
4 |
5 | ```bash
6 | git clone repo
7 | cd express_graphql
8 | npm install
9 | # Setup database
10 | createdb express_graphql_development
11 | node_modules/sequelize-cli/bin/sequelize db:migrate
12 | node_modules/sequelize-cli/bin/sequelize db:seed:all
13 | # Run server
14 | DEBUG=express_graphql:* npm start
15 | ```
16 |
17 | [Visit browser](http://localhost:3000/)
18 |
19 | ### Supported API Queries
20 |
21 | ```
22 | {
23 | allPosts {
24 | id,
25 | title
26 | body
27 | user {
28 | id
29 | first_name
30 | }
31 | comments{
32 | id
33 | body
34 | }
35 |
36 | }
37 | }
38 | ```
39 |
40 | ```
41 | {
42 | post(id: 1) {
43 | id,
44 | title
45 | body
46 | user {
47 | id
48 | first_name
49 | }
50 | comments{
51 | id
52 | body
53 | }
54 |
55 | }
56 | }
57 | ```
58 |
--------------------------------------------------------------------------------
/javascript/express_graphql/api/types/commentType.js:
--------------------------------------------------------------------------------
1 | import userType from './userType';
2 | import models from '../../models';
3 | import { resolver } from 'graphql-sequelize';
4 | import { GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLInt, GraphQLString} from 'graphql';
5 |
6 | let commentType = new GraphQLObjectType({
7 | name: 'Comment',
8 | description: 'A comment',
9 | fields: {
10 | id: {
11 | type: new GraphQLNonNull(GraphQLInt),
12 | description: 'The id of the comment.',
13 | },
14 | body: {
15 | type: GraphQLString,
16 | description: 'The body of the comment'
17 | },
18 | user: {
19 | type: userType,
20 | description: 'The user of the comment',
21 | resolve: resolver(models.User)
22 | },
23 | }
24 | });
25 |
26 | module.exports = commentType;
27 |
--------------------------------------------------------------------------------
/javascript/express_graphql/api/types/postType.js:
--------------------------------------------------------------------------------
1 | import commentType from './commentType';
2 | import userType from './userType';
3 | import models from '../../models';
4 | import { resolver } from 'graphql-sequelize';
5 | import { GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLInt, GraphQLString} from 'graphql';
6 |
7 | let postType = new GraphQLObjectType({
8 | name: 'Post',
9 | description: 'A post',
10 | fields: {
11 | id: {
12 | type: new GraphQLNonNull(GraphQLInt),
13 | description: 'The id of the post.',
14 | },
15 | title: {
16 | type: GraphQLString,
17 | description: 'The title of the post'
18 | },
19 | body: {
20 | type: GraphQLString,
21 | description: 'The body of the post'
22 | },
23 | user: {
24 | type: userType,
25 | description: 'The user of the post',
26 | resolve: resolver(models.Post.User)
27 | },
28 | comments: {
29 | type: new GraphQLList(commentType),
30 | resolve: resolver(models.Post.Comments)
31 | }
32 | }
33 | });
34 |
35 | module.exports = postType;
36 |
--------------------------------------------------------------------------------
/javascript/express_graphql/api/types/userType.js:
--------------------------------------------------------------------------------
1 | import postType from './postType';
2 | import commentType from './commentType';
3 | import models from '../../models';
4 | import { resolver, attributeFields } from 'graphql-sequelize';
5 | import { GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLInt, GraphQLString} from 'graphql';
6 |
7 | let userType = new GraphQLObjectType({
8 | name: 'User',
9 | description: 'A user',
10 | fields: () => ({
11 | id: {
12 | type: new GraphQLNonNull(GraphQLInt),
13 | description: 'The id of the user.',
14 | },
15 | first_name: {
16 | type: GraphQLString,
17 | description: 'The first name of the user.',
18 | },
19 | last_name: {
20 | type: GraphQLString,
21 | description: 'The last name of the user.',
22 | },
23 | username: {
24 | type: GraphQLString,
25 | description: 'The username of the user.',
26 | },
27 |
28 | email: {
29 | type: GraphQLString,
30 | description: 'The email of the user.',
31 | },
32 | })
33 | });
34 |
35 | module.exports = userType;
36 |
--------------------------------------------------------------------------------
/javascript/express_graphql/config/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "development": {
3 | "username": "gaurav",
4 | "password": null,
5 | "database": "express_graphql_development",
6 | "host": "127.0.0.1",
7 | "dialect": "postgres"
8 | },
9 | "test": {
10 | "username": "gaurav",
11 | "password": null,
12 | "database": "express_graphql_test",
13 | "host": "127.0.0.1",
14 | "dialect": "postgres"
15 | },
16 | "production": {
17 | "username": "gaurav",
18 | "password": null,
19 | "database": "express_graphql_production",
20 | "host": "127.0.0.1",
21 | "dialect": "postgres"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/javascript/express_graphql/migrations/20160521095312-create-user.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = {
3 | up: function(queryInterface, Sequelize) {
4 | return queryInterface.createTable('Users', {
5 | id: {
6 | allowNull: false,
7 | autoIncrement: true,
8 | primaryKey: true,
9 | type: Sequelize.INTEGER
10 | },
11 | first_name: {
12 | type: Sequelize.STRING
13 | },
14 | last_name: {
15 | type: Sequelize.STRING
16 | },
17 | email: {
18 | type: Sequelize.STRING,
19 | index: true
20 | },
21 | username: {
22 | type: Sequelize.STRING,
23 | index: true
24 | },
25 | createdAt: {
26 | allowNull: false,
27 | type: Sequelize.DATE
28 | },
29 | updatedAt: {
30 | allowNull: false,
31 | type: Sequelize.DATE
32 | }
33 | });
34 | },
35 | down: function(queryInterface, Sequelize) {
36 | return queryInterface.dropTable('Users');
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/javascript/express_graphql/migrations/20160521095507-create-post.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = {
3 | up: function(queryInterface, Sequelize) {
4 | return queryInterface.createTable('Posts', {
5 | id: {
6 | allowNull: false,
7 | autoIncrement: true,
8 | primaryKey: true,
9 | type: Sequelize.INTEGER
10 | },
11 | title: {
12 | type: Sequelize.STRING
13 | },
14 | body: {
15 | type: Sequelize.TEXT
16 | },
17 | UserId: {
18 | type: Sequelize.INTEGER,
19 | index: true,
20 | foreignKey: true
21 | },
22 | createdAt: {
23 | allowNull: false,
24 | type: Sequelize.DATE
25 | },
26 | updatedAt: {
27 | allowNull: false,
28 | type: Sequelize.DATE
29 | }
30 | });
31 | },
32 | down: function(queryInterface, Sequelize) {
33 | return queryInterface.dropTable('Posts');
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/javascript/express_graphql/migrations/20160521100324-create-comment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = {
3 | up: function(queryInterface, Sequelize) {
4 | return queryInterface.createTable('Comments', {
5 | id: {
6 | allowNull: false,
7 | autoIncrement: true,
8 | primaryKey: true,
9 | type: Sequelize.INTEGER
10 | },
11 | body: {
12 | type: Sequelize.TEXT
13 | },
14 | PostId: {
15 | type: Sequelize.INTEGER,
16 | index: true,
17 | foreignKey: true
18 | },
19 | UserId: {
20 | type: Sequelize.INTEGER,
21 | index: true,
22 | foreignKey: true
23 | },
24 | createdAt: {
25 | allowNull: false,
26 | type: Sequelize.DATE
27 | },
28 | updatedAt: {
29 | allowNull: false,
30 | type: Sequelize.DATE
31 | }
32 | });
33 | },
34 | down: function(queryInterface, Sequelize) {
35 | return queryInterface.dropTable('Comments');
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/javascript/express_graphql/models/comment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = function(sequelize, DataTypes) {
3 | var Comment = sequelize.define('Comment', {
4 | body: DataTypes.TEXT,
5 | post_id: DataTypes.INTEGER,
6 | user_id: DataTypes.INTEGER
7 | }, {
8 | classMethods: {
9 | associate: function(models) {
10 | Comment.User = Comment.belongsTo(models.User, {
11 | onDelete: "CASCADE",
12 | foreignKey: {
13 | allowNull: false
14 | }
15 | });
16 |
17 | Comment.Post = Comment.belongsTo(models.Post, {
18 | onDelete: "CASCADE",
19 | foreignKey: {
20 | allowNull: false
21 | }
22 | });
23 | }
24 | }
25 | });
26 | return Comment;
27 | };
28 |
--------------------------------------------------------------------------------
/javascript/express_graphql/models/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var fs = require('fs');
4 | var path = require('path');
5 | var Sequelize = require('sequelize');
6 | var basename = path.basename(module.filename);
7 | var env = process.env.NODE_ENV || 'development';
8 | var config = require(__dirname + '/../config/config.json')[env];
9 | var db = {};
10 |
11 | if (config.use_env_variable) {
12 | var sequelize = new Sequelize(process.env[config.use_env_variable]);
13 | } else {
14 | var sequelize = new Sequelize(config.database, config.username, config.password, config);
15 | }
16 |
17 | fs
18 | .readdirSync(__dirname)
19 | .filter(function(file) {
20 | return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
21 | })
22 | .forEach(function(file) {
23 | var model = sequelize['import'](path.join(__dirname, file));
24 | db[model.name] = model;
25 | });
26 |
27 | Object.keys(db).forEach(function(modelName) {
28 | if (db[modelName].associate) {
29 | db[modelName].associate(db);
30 | }
31 | });
32 |
33 | db.sequelize = sequelize;
34 | db.Sequelize = Sequelize;
35 |
36 | module.exports = db;
37 |
--------------------------------------------------------------------------------
/javascript/express_graphql/models/post.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = function(sequelize, DataTypes) {
3 | var Post = sequelize.define('Post', {
4 | title: DataTypes.STRING,
5 | body: DataTypes.TEXT,
6 | user_id: DataTypes.INTEGER
7 | }, {
8 | classMethods: {
9 | associate: function(models) {
10 | Post.Comments = Post.hasMany(models.Comment);
11 | Post.User = Post.belongsTo(models.User, {
12 | onDelete: "CASCADE",
13 | foreignKey: {
14 | allowNull: false
15 | }
16 | });
17 | }
18 | }
19 | });
20 | return Post;
21 | };
22 |
--------------------------------------------------------------------------------
/javascript/express_graphql/models/user.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = function(sequelize, DataTypes) {
3 | var User = sequelize.define('User', {
4 | first_name: DataTypes.STRING,
5 | last_name: DataTypes.STRING,
6 | email: DataTypes.STRING,
7 | username: DataTypes.STRING
8 | }, {
9 | classMethods: {
10 | associate: function(models) {
11 | User.Comments = User.hasMany(models.Comment);
12 | User.Posts = User.hasMany(models.Post);
13 | }
14 | }
15 | });
16 | return User;
17 | };
18 |
--------------------------------------------------------------------------------
/javascript/express_graphql/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express_graphql",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "nodemon bin/www --exec babel-node --presets es2015,stage-2"
7 | },
8 | "dependencies": {
9 | "babel-core": "^6.9.0",
10 | "babel-polyfill": "^6.9.0",
11 | "babel-preset-es2015": "^6.9.0",
12 | "babel-preset-stage-0": "^6.5.0",
13 | "body-parser": "~1.13.2",
14 | "cookie-parser": "~1.3.5",
15 | "debug": "~2.2.0",
16 | "express": "~4.13.1",
17 | "express-graphql": "^0.5.1",
18 | "graphql": "^0.5.0",
19 | "graphql-sequelize": "^2.0.0",
20 | "jade": "~1.11.0",
21 | "lodash": "^4.12.0",
22 | "morgan": "~1.6.1",
23 | "sequelize": "^3.23.2",
24 | "sequelize-cli": "^2.4.0",
25 | "serve-favicon": "~2.3.0",
26 | "sqlite3": "^3.1.4"
27 | },
28 | "devDependencies": {
29 | "babel-cli": "^6.9.0",
30 | "nodemon": "^1.9.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/javascript/express_graphql/seeders/20160521103212-user.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | up: function (queryInterface, Sequelize) {
5 | return queryInterface.bulkInsert('Users', [{
6 | first_name: 'John',
7 | last_name: 'Doe',
8 | email: 'john@doe.com',
9 | username: 'johndoe',
10 | createdAt: new Date((new Date()).getTime()),
11 | updatedAt: new Date((new Date()).getTime())
12 | },
13 | {
14 | first_name: 'Maggie',
15 | last_name: 'Turner',
16 | email: 'maggie@turner.com',
17 | username: 'maggie',
18 | createdAt: new Date((new Date()).getTime()),
19 | updatedAt: new Date((new Date()).getTime())
20 | }
21 | ], {});
22 | },
23 |
24 | down: function (queryInterface, Sequelize) {
25 | return queryInterface.bulkDelete('Users', null, {});
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/javascript/express_graphql/seeders/20160521111530-post.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | up: function (queryInterface, Sequelize) {
5 | return queryInterface.bulkInsert('Posts', [{
6 | title: 'First post title',
7 | body: 'First post body',
8 | UserId: 1,
9 | createdAt: new Date((new Date()).getTime()),
10 | updatedAt: new Date((new Date()).getTime())
11 | },
12 | {
13 | title: 'Second post title',
14 | body: 'Second post body',
15 | UserId: 2,
16 | createdAt: new Date((new Date()).getTime()),
17 | updatedAt: new Date((new Date()).getTime())
18 | }
19 | ], {});
20 | },
21 |
22 | down: function (queryInterface, Sequelize) {
23 | queryInterface.bulkDelete('Posts', null, {});
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/javascript/express_graphql/seeders/20160521111557-comment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | up: function (queryInterface, Sequelize) {
5 | return queryInterface.bulkInsert('Comments', [{
6 | body: 'First post comment',
7 | UserId: 1,
8 | PostId: 1,
9 | createdAt: new Date((new Date()).getTime()),
10 | updatedAt: new Date((new Date()).getTime())
11 | },
12 | {
13 | body: 'First post second comment',
14 | UserId: 1,
15 | PostId: 1,
16 | createdAt: new Date((new Date()).getTime()),
17 | updatedAt: new Date((new Date()).getTime())
18 | },
19 | {
20 | body: 'Second post first comment',
21 | UserId: 2,
22 | PostId: 2,
23 | createdAt: new Date((new Date()).getTime()),
24 | updatedAt: new Date((new Date()).getTime())
25 | }
26 | ], {});
27 | },
28 |
29 | down: function (queryInterface, Sequelize) {
30 | queryInterface.bulkDelete('Comments', null, {});
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "development": {
4 | "presets": ["es2015", "stage-0"],
5 | "plugins": ["transform-async-to-generator"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | npm-debug.*
3 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "esnext": true,
4 | "bitwise": true,
5 | "camelcase": true,
6 | "curly": true,
7 | "eqeqeq": true,
8 | "immed": true,
9 | "indent": 2,
10 | "latedef": true,
11 | "newcap": true,
12 | "noarg": true,
13 | "quotmark": "single",
14 | "regexp": true,
15 | "undef": true,
16 | "unused": true,
17 | "strict": true,
18 | "trailing": true,
19 | "smarttabs": true,
20 | "white": true
21 | }
22 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Koa GraphQL Server
2 |
3 | ## Getting started locally
4 |
5 | ```bash
6 | git clone repo
7 | cd express_graphql
8 | npm install
9 |
10 | # ORM for database interaction
11 | npm install bookshelf -g -s
12 | # Query building and schema/migration/seed generation
13 | npm install knex -g -s
14 | # Setup database
15 | createdb express_graphql_development
16 | # make sure knex installed globally or refer local installation
17 | knex migrate:latest
18 | knex seed:run
19 | # Run server
20 | DEBUG=koa_graphql:* npm start
21 | ```
22 |
23 | [Visit browser](http://localhost:3000/)
24 |
25 | ### Supported API Queries
26 |
27 | ```
28 | {
29 | allPosts {
30 | id,
31 | title
32 | body
33 | user {
34 | id
35 | first_name
36 | }
37 | comments{
38 | id
39 | body
40 | }
41 |
42 | }
43 | }
44 | ```
45 |
46 | ```
47 | {
48 | post(id: 1) {
49 | id,
50 | title
51 | body
52 | user {
53 | id
54 | first_name
55 | }
56 | comments{
57 | id
58 | body
59 | }
60 |
61 | }
62 | }
63 | ```
64 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/api/types/commentType.js:
--------------------------------------------------------------------------------
1 | import PostType from './postType';
2 | import UserType from './userType';
3 |
4 | import {
5 | GraphQLBoolean,
6 | GraphQLID,
7 | GraphQLInt,
8 | GraphQLList,
9 | GraphQLNonNull,
10 | GraphQLObjectType,
11 | GraphQLSchema,
12 | GraphQLString,
13 | } from 'graphql';
14 |
15 | const CommentType = new GraphQLObjectType({
16 | name: 'CommentType',
17 | fields: () => ({
18 | id: { type: new GraphQLNonNull(GraphQLID) },
19 | body: {
20 | type: GraphQLString,
21 | resolve: (obj) => obj.body,
22 | },
23 | post: {
24 | type: PostType,
25 | resolve: (obj) => obj.post,
26 | },
27 | user: {
28 | type: UserType,
29 | resolve: (obj) => obj.user,
30 | },
31 | }),
32 | });
33 |
34 | export default CommentType;
35 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/api/types/postType.js:
--------------------------------------------------------------------------------
1 | import CommentType from './commentType';
2 | import UserType from './userType';
3 |
4 | import {
5 | GraphQLBoolean,
6 | GraphQLID,
7 | GraphQLInt,
8 | GraphQLList,
9 | GraphQLNonNull,
10 | GraphQLObjectType,
11 | GraphQLSchema,
12 | GraphQLString,
13 | } from 'graphql';
14 |
15 | const PostType = new GraphQLObjectType({
16 | name: 'PostType',
17 | fields: () => ({
18 | id: { type: new GraphQLNonNull(GraphQLID) },
19 | title: {
20 | type: GraphQLString,
21 | resolve: (obj) => obj.title,
22 | },
23 | body: {
24 | type: GraphQLString,
25 | resolve: (obj) => obj.body,
26 | },
27 | comments: {
28 | type: new GraphQLList(CommentType),
29 | resolve: (obj) => obj.comments,
30 | },
31 | user: {
32 | type: UserType,
33 | resolve: (obj) => obj.user,
34 | },
35 | }),
36 | });
37 |
38 | export default PostType;
39 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/api/types/userType.js:
--------------------------------------------------------------------------------
1 | import PostType from './postType';
2 | import CommentType from './commentType';
3 |
4 | import {
5 | GraphQLBoolean,
6 | GraphQLID,
7 | GraphQLInt,
8 | GraphQLList,
9 | GraphQLNonNull,
10 | GraphQLObjectType,
11 | GraphQLSchema,
12 | GraphQLString,
13 | } from 'graphql';
14 |
15 | const UserType = new GraphQLObjectType({
16 | name: 'UserType',
17 | fields: () => ({
18 | id: { type: new GraphQLNonNull(GraphQLID) },
19 | first_name: {
20 | type: GraphQLString,
21 | resolve: (obj) => obj.first_name,
22 | },
23 | last_name: {
24 | type: GraphQLString,
25 | resolve: (obj) => obj.last_name,
26 | },
27 | username: {
28 | type: GraphQLString,
29 | resolve: (obj) => obj.username,
30 | },
31 | email: {
32 | type: GraphQLString,
33 | resolve: (obj) => obj.email,
34 | },
35 | posts: {
36 | type: new GraphQLList(PostType),
37 | resolve: (obj) => obj.posts
38 | },
39 | comments: {
40 | type: new GraphQLList(CommentType),
41 | resolve: (obj) => obj.comments
42 | },
43 | }),
44 | });
45 |
46 | export default UserType;
47 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const compress = require('koa-compress');
3 | const logger = require('koa-logger');
4 | const koa = require('koa');
5 | const path = require('path');
6 | var mount = require('koa-mount');
7 | var convert = require('koa-convert');
8 | var graphqlHTTP = require('koa-graphql');
9 | var Schema = require('./api/schema');
10 |
11 | const app = module.exports = koa();
12 |
13 | // Logger
14 | app.use(logger());
15 | app.use(mount('/', graphqlHTTP({ schema: Schema, graphiql: true })));
16 |
17 | // Compress
18 | app.use(compress());
19 |
20 | if (!module.parent) {
21 | app.listen(3000);
22 | console.log('listening on port 3000');
23 | }
24 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/bookshelf.js:
--------------------------------------------------------------------------------
1 | // Update with your config settings.
2 | var knex = require('knex')({
3 | client: 'postgres',
4 | connection: {
5 | host : '127.0.0.1',
6 | user : 'gaurav',
7 | database : 'koa_graphql_development'
8 | },
9 | pool: {
10 | min: 2,
11 | max: 10
12 | },
13 | migrations: {
14 | tableName: 'knex_migrations'
15 | }
16 | }
17 | );
18 |
19 | var bookshelf = module.exports = require('bookshelf')(knex);
20 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/migrations/20160521155821_users.js:
--------------------------------------------------------------------------------
1 | exports.up = function(knex, Promise) {
2 | return knex.schema.createTable('users', function (table) {
3 | table.increments();
4 | table.string('first_name');
5 | table.string('last_name');
6 | table.string('username');
7 | table.string('email');
8 | table.unique('email');
9 | table.timestamps();
10 | });
11 | };
12 |
13 | exports.down = function(knex, Promise) {
14 | return knex.schema.dropTable('users');
15 | };
16 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/migrations/20160521155829_posts.js:
--------------------------------------------------------------------------------
1 | exports.up = function(knex, Promise) {
2 | return knex.schema.createTable('posts', function (table) {
3 | table.increments();
4 | table.string('title');
5 | table.string('body');
6 | table.integer('user_id');
7 | table.foreign('user_id').references('user_id');
8 | table.index('user_id');
9 | table.timestamps();
10 | });
11 | };
12 |
13 | exports.down = function(knex, Promise) {
14 | return knex.schema.dropTable('posts');
15 | };
16 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/migrations/20160521155833_comments.js:
--------------------------------------------------------------------------------
1 | exports.up = function(knex, Promise) {
2 | return knex.schema.createTable('comments', function (table) {
3 | table.increments();
4 | table.string('body');
5 | table.integer('user_id');
6 | table.integer('post_id');
7 | table.foreign(['user_id', 'post_id']).references(['user_id', 'post_id']);
8 | table.index(['user_id', 'post_id']);
9 | table.timestamps();
10 | });
11 | };
12 |
13 | exports.down = function(knex, Promise) {
14 | return knex.schema.dropTable('comments');
15 | };
16 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/models/comment.js:
--------------------------------------------------------------------------------
1 | import bookshelf from '../bookshelf';
2 | import Post from './post';
3 | import User from './user';
4 |
5 | const Comment = bookshelf.Model.extend({
6 | tableName: 'comments',
7 | hasTimestamps: ['created_at', 'updated_at'],
8 | post: function() {
9 | return this.belongsTo(Post);
10 | },
11 | user: function() {
12 | return this.belongsTo(User);
13 | }
14 | });
15 |
16 | export default Comment;
17 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/models/post.js:
--------------------------------------------------------------------------------
1 | import bookshelf from '../bookshelf';
2 | import Comment from './comment';
3 | import User from './user';
4 |
5 | const Post = bookshelf.Model.extend({
6 | tableName: 'posts',
7 | hasTimestamps: ['created_at', 'updated_at'],
8 | comments: function() {
9 | return this.hasMany(Comment);
10 | },
11 | user: function() {
12 | return this.belongsTo(User);
13 | }
14 | });
15 |
16 | export default Post;
17 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/models/user.js:
--------------------------------------------------------------------------------
1 | import bookshelf from '../bookshelf';
2 | import Comment from './comment';
3 | import Post from './post';
4 |
5 | const User = bookshelf.Model.extend({
6 | tableName: 'users',
7 | hasTimestamps: ['created_at', 'updated_at'],
8 | comments: function() {
9 | return this.hasMany(Comment);
10 | },
11 | posts: function() {
12 | return this.hasMany(Post);
13 | }
14 | });
15 |
16 | export default User;
17 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "koa_graphql",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "nodemon app.js --exec babel-node",
7 | "test": "mocha"
8 | },
9 | "dependencies": {
10 | "bookshelf": "^0.9.5",
11 | "co-body": "^4.0.0",
12 | "co-views": "^2.1.0",
13 | "graphql": "^0.5.0",
14 | "knex": "^0.11.3",
15 | "koa": "^1.2.0",
16 | "koa-compress": "^1.0.6",
17 | "koa-convert": "^1.2.0",
18 | "koa-graphql": "^0.5.1",
19 | "koa-logger": "^1.2.0",
20 | "koa-mount": "^1.3.0",
21 | "koa-route": "^2.4.2",
22 | "koa-session": "^3.3.1",
23 | "koa-static": "^2.0.0",
24 | "nodemon": "^1.9.2",
25 | "pg": "^4.5.5",
26 | "swig": "^1.3.2"
27 | },
28 | "devDependencies": {
29 | "babel-cli": "^6.9.0",
30 | "babel-core": "^6.9.0",
31 | "babel-plugin-transform-async-to-generator": "^6.8.0",
32 | "babel-preset-es2015": "^6.9.0",
33 | "babel-preset-es2015-node5": "^1.2.0",
34 | "babel-preset-stage-0": "^6.5.0",
35 | "mocha": "^2.4.5",
36 | "supertest": "^0.12.1"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/seeds/comments.js:
--------------------------------------------------------------------------------
1 |
2 | exports.seed = function(knex, Promise) {
3 | return Promise.join(
4 | // Deletes ALL existing entries
5 | knex('comments').del(),
6 |
7 | // Inserts seed entries
8 | knex('comments').insert({
9 | id: 1,
10 | body: 'First post comment',
11 | user_id: 1,
12 | post_id: 1,
13 | created_at: new Date((new Date()).getTime()),
14 | updated_at: new Date((new Date()).getTime())
15 | }),
16 | knex('comments').insert({
17 | id: 2,
18 | body: 'Second post comment',
19 | user_id: 2,
20 | post_id: 2,
21 | created_at: new Date((new Date()).getTime()),
22 | updated_at: new Date((new Date()).getTime())
23 | }),
24 | knex('comments').insert({
25 | id: 3,
26 | body: 'Third post comment',
27 | user_id: 3,
28 | post_id: 3,
29 | created_at: new Date((new Date()).getTime()),
30 | updated_at: new Date((new Date()).getTime())
31 | })
32 | );
33 | };
34 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/seeds/posts.js:
--------------------------------------------------------------------------------
1 |
2 | exports.seed = function(knex, Promise) {
3 | return Promise.join(
4 | // Deletes ALL existing entries
5 | knex('posts').del(),
6 |
7 | // Inserts seed entries
8 | knex('posts').insert({
9 | id: 1,
10 | title: 'First post title',
11 | body: 'First post body',
12 | user_id: 1,
13 | created_at: new Date((new Date()).getTime()),
14 | updated_at: new Date((new Date()).getTime())
15 | }),
16 | knex('posts').insert({
17 | id: 2,
18 | title: 'Second post title',
19 | body: 'Second post body',
20 | user_id: 2,
21 | created_at: new Date((new Date()).getTime()),
22 | updated_at: new Date((new Date()).getTime())
23 | }),
24 | knex('posts').insert({
25 | id: 3,
26 | title: 'Third post title',
27 | body: 'Third post body',
28 | user_id: 3,
29 | created_at: new Date((new Date()).getTime()),
30 | updated_at: new Date((new Date()).getTime())
31 | })
32 | );
33 | };
34 |
--------------------------------------------------------------------------------
/javascript/koa_graphql/seeds/users.js:
--------------------------------------------------------------------------------
1 |
2 | exports.seed = function(knex, Promise) {
3 | return Promise.join(
4 | // Deletes ALL existing entries
5 | knex('users').del(),
6 |
7 | // Inserts seed entries
8 | knex('users').insert({
9 | id: 1,
10 | first_name: 'John',
11 | last_name: 'Doe',
12 | username: 'johndoe',
13 | email: 'john@doe.com',
14 | created_at: new Date((new Date()).getTime()),
15 | updated_at: new Date((new Date()).getTime())
16 | }),
17 | knex('users').insert({
18 | id: 2,
19 | first_name: 'Maggie',
20 | last_name: 'Turner',
21 | username: 'maggie',
22 | email: 'maggie@turner.com',
23 | created_at: new Date((new Date()).getTime()),
24 | updated_at: new Date((new Date()).getTime())
25 | }),
26 | knex('users').insert({
27 | id: 3,
28 | first_name: 'Sam',
29 | last_name: 'Smith',
30 | username: 'sam',
31 | email: 'sam@smith.com',
32 | created_at: new Date((new Date()).getTime()),
33 | updated_at: new Date((new Date()).getTime())
34 | })
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 | 1.2.0-standard-minifiers-package
10 | 1.2.0-meteor-platform-split
11 | 1.2.0-cordova-changes
12 | 1.2.0-breaking-changes
13 | 1.3.0-split-minifiers-package
14 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | 183m4ka1p4y3rwjf3bvb
8 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | # Check this file (and the other files in this directory) into your repository.
3 | #
4 | # 'meteor add' and 'meteor remove' will edit this file for you,
5 | # but you can also edit it by hand.
6 |
7 | meteor-base # Packages every Meteor app needs to have
8 | mobile-experience # Packages for a great mobile UX
9 | mongo # The database Meteor supports right now
10 | blaze-html-templates # Compile .html files into Meteor Blaze views
11 | reactive-var # Reactive variable for tracker
12 | jquery # Helpful client-side library
13 | tracker # Meteor's client-side reactive programming library
14 |
15 | standard-minifier-css # CSS minifier run for production mode
16 | standard-minifier-js # JS minifier run for production mode
17 | es5-shim # ECMAScript 5 compatibility for older browsers.
18 | ecmascript # Enable ECMAScript2015+ syntax in app code
19 |
20 | autopublish # Publish all data to the clients (for prototyping)
21 | insecure # Allow all DB writes from clients (for prototyping)
22 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.meteor/platforms:
--------------------------------------------------------------------------------
1 | server
2 | browser
3 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.3.2.4
2 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Meteor GraphQL Server
2 |
3 | ## Getting started locally
4 |
5 | ```bash
6 | git clone repo
7 | cd express_graphql
8 | npm install
9 |
10 | meteor npm install
11 | meteor
12 | ```
13 |
14 | [Visit browser](http://localhost:3000/graphql)
15 |
16 | ### Supported API Queries
17 |
18 | ```
19 | {
20 | allPosts {
21 | _id,
22 | title
23 | body
24 | user {
25 | _id
26 | first_name
27 | }
28 | comments{
29 | _id
30 | body
31 | }
32 |
33 | }
34 | }
35 | ```
36 |
37 | ```
38 | {
39 | post(id: "qEsSyu5wHec6e67AW") {
40 | _id,
41 | title
42 | body
43 | user {
44 | _id
45 | first_name
46 | }
47 | comments{
48 | _id
49 | body
50 | }
51 |
52 | }
53 | }
54 | ```
55 |
56 | ### Field aliases
57 |
58 | ```
59 | {
60 | posts: allPosts {
61 | _id
62 | body
63 | comments {
64 | _id
65 | body
66 | user {
67 | first_name
68 | last_name
69 | }
70 | }
71 | user {
72 | first_name
73 | last_name
74 | }
75 | }
76 | }
77 | ```
78 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/client/main.html:
--------------------------------------------------------------------------------
1 |
2 | This is main page
3 | Go to editor
4 |
5 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/imports/collections/comments.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 | export const Comments = new Mongo.Collection('comments');
3 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/imports/collections/posts.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 | export const Posts = new Mongo.Collection('posts');
3 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/imports/collections/schemas.js:
--------------------------------------------------------------------------------
1 | import Posts from './posts';
2 | import Comments from './comments';
3 | import Users from './users';
4 |
5 | let Schema = {};
6 |
7 | Schema.User = new SimpleSchema({
8 | name: {
9 | first_name: String,
10 | last_name: String,
11 | username: String,
12 | email: String
13 | },
14 | });
15 |
16 | Schema.Post = new SimpleSchema({
17 | title: {
18 | type: String,
19 | max: 140
20 | },
21 | body: {
22 | type: String,
23 | max: 2000
24 | },
25 | user: {
26 | type: Schema.User,
27 | },
28 | });
29 |
30 | Schema.Comment = new SimpleSchema({
31 | body: {
32 | type: String,
33 | max: 2000
34 | },
35 | user: {
36 | type: Schema.User,
37 | },
38 | post: {
39 | type: Schema.Post,
40 | },
41 | });
42 |
43 | Users.attachSchema(Schema.User);
44 | Posts.attachSchema(Schema.Post);
45 | Comments.attachSchema(Schema.Comment);
46 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/imports/collections/users.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 | export const Users = new Mongo.Collection('users');
3 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "meteor_graphql",
3 | "private": true,
4 | "scripts": {
5 | "start": "meteor run"
6 | },
7 | "dependencies": {
8 | "apollo-client": "^0.3.13",
9 | "apollo-server": "^0.1.3",
10 | "express": "^4.13.4",
11 | "graphql": "^0.6.0",
12 | "graphql-tools": "^0.6.0",
13 | "http-proxy-middleware": "^0.15.2",
14 | "invariant": "^2.2.1",
15 | "meteor-node-stubs": "~0.2.0",
16 | "react": "^15.1.0",
17 | "react-addons-pure-render-mixin": "^15.1.0",
18 | "react-apollo": "^0.3.8",
19 | "react-dom": "^15.1.0",
20 | "tracker-component": "^1.3.21"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/server/fixtures/users.js:
--------------------------------------------------------------------------------
1 | const UsersSeed = [
2 | {
3 | first_name: 'John',
4 | last_name: 'Doe',
5 | username: 'johndoe',
6 | email: 'johndoe@doe.com'
7 | },
8 | {
9 | first_name: 'Maggie',
10 | last_name: 'Turner',
11 | username: 'maggie',
12 | email: 'maggie@turner.com'
13 | }
14 | ];
15 |
16 | export default UsersSeed;
17 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/server/main.js:
--------------------------------------------------------------------------------
1 | import { Meteor } from 'meteor/meteor';
2 | import { apolloServer } from 'apollo-server';
3 | import express from 'express';
4 | import proxyMiddleware from 'http-proxy-middleware';
5 | import { check } from 'meteor/check';
6 | import { Comments } from '../imports/collections/comments';
7 | import { Posts } from '../imports/collections/posts';
8 |
9 | import { schema, resolvers } from '/imports/api/schema';
10 |
11 | const GRAPHQL_PORT = 4000;
12 |
13 | const graphQLServer = express();
14 |
15 | graphQLServer.use('/', apolloServer(async (req) => {
16 | return {
17 | graphiql: true,
18 | pretty: true,
19 | schema,
20 | resolvers,
21 | };
22 | }));
23 |
24 | graphQLServer.listen(GRAPHQL_PORT, () => console.log(
25 | `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}`
26 | ));
27 |
28 | WebApp.rawConnectHandlers.use(proxyMiddleware(`http://localhost:${GRAPHQL_PORT}/graphql`));
29 |
30 | Meteor.startup(function () {
31 | Posts._ensureIndex({ "user": 1});
32 | Comments._ensureIndex({ "post": 1});
33 | Comments._ensureIndex({ "user": 1});
34 | });
35 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/server/publications/posts.js:
--------------------------------------------------------------------------------
1 | import { Posts } from '../../imports/collections/posts';
2 |
--------------------------------------------------------------------------------
/javascript/meteor_graphql/server/seeds.js:
--------------------------------------------------------------------------------
1 | import { Posts } from '../imports/collections/posts';
2 | import { Comments } from '../imports/collections/comments';
3 | import { Users } from '../imports/collections/users';
4 |
5 | import UsersSeed from './fixtures/users';
6 |
7 | Meteor.methods({
8 | 'Database.seed': function() {
9 | _.forEach(UsersSeed, function(user) {
10 | let userObj = Users.insert(user, function(error, result) {
11 | console.log('Users added', result);
12 | });
13 |
14 | let postObject = Posts.insert({
15 | title: 'this is post title',
16 | body: 'this is post body',
17 | user: userObj,
18 | }, function(error, result) {
19 | const Comment = {
20 | post: postObject,
21 | user: userObj,
22 | body: 'this is a comment for this post',
23 | };
24 | Comments.insert(Comment, function(error, result) {
25 | console.log('Comment added for', postObject);
26 | });
27 | });
28 | });
29 | }
30 | });
31 |
--------------------------------------------------------------------------------
/php/README.md:
--------------------------------------------------------------------------------
1 | # PHP based web frameworks
2 |
3 | A set of GraphQL server implementation on popular PHP web frameworks.
4 |
5 | ## Frameworks
6 | * Laravel
7 |
8 | ```bash
9 | $ brew update
10 | $ brew install homebrew/php/php70 --with-apache --with-mysql --with-postgresql --with-intl
11 | $ php -v
12 | PHP 7.0.7 (cli) (built: Jun 6 2016 18:09:34) ( NTS )
13 | Copyright (c) 1997-2016 The PHP Group
14 | Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologie
15 | ```
16 |
17 | Then, follow the example readme to setup application locally.
18 |
--------------------------------------------------------------------------------
/php/laravel_graphql/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.css linguist-vendored
3 | *.scss linguist-vendored
4 |
--------------------------------------------------------------------------------
/php/laravel_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /node_modules
3 | /public/storage
4 | Homestead.yaml
5 | Homestead.json
6 | .env
7 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Comment.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\User');
15 | }
16 |
17 | public function post() {
18 | return $this->belongsTo('App\Post');
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Console/Commands/Inspire.php:
--------------------------------------------------------------------------------
1 | comment(PHP_EOL.Inspiring::quote().PHP_EOL);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')
28 | // ->hourly();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Events/Event.php:
--------------------------------------------------------------------------------
1 | 'CommentsQuery'
11 | ];
12 |
13 | public function type()
14 | {
15 | return Type::listOf(GraphQL::type('comment'));
16 | }
17 |
18 | public function resolve($root, $args)
19 | {
20 | return $root->comments;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Query/PostQuery.php:
--------------------------------------------------------------------------------
1 | 'PostQuery'
11 | ];
12 |
13 | public function type()
14 | {
15 | return GraphQL::type('post');
16 | }
17 |
18 | public function resolve($root, $args)
19 | {
20 | return $root->post;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Query/PostsQuery.php:
--------------------------------------------------------------------------------
1 | 'PostsQuery'
12 | ];
13 |
14 | public function type()
15 | {
16 | return Type::listOf(GraphQL::type('post'));
17 | }
18 |
19 | public function args()
20 | {
21 | return [
22 | 'id' => ['name' => 'id', 'type' => Type::Int()],
23 | ];
24 | }
25 |
26 | public function resolve($root, $args)
27 | {
28 | if(isset($args['id']))
29 | {
30 | return Post::where('id' , $args['id'])->with('user', 'comments')->get();
31 | }
32 | else
33 | {
34 | $posts = Post::query();
35 | return $posts->with('user', 'comments')->get();
36 | }
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Query/UserQuery.php:
--------------------------------------------------------------------------------
1 | 'UserQuery'
11 | ];
12 |
13 | public function type()
14 | {
15 | return Type::nonNull(GraphQL::type('user'));
16 | }
17 |
18 | public function resolve($root, $args)
19 | {
20 | return $root->user;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Query/UsersQuery.php:
--------------------------------------------------------------------------------
1 | 'Users query'
12 | ];
13 |
14 | public function type()
15 | {
16 | return Type::listOf(GraphQL::type('user'));
17 | }
18 |
19 | public function args()
20 | {
21 | return [
22 | 'id' => ['name' => 'id', 'type' => Type::string()]
23 | ];
24 | }
25 |
26 | public function resolve($root, $args)
27 | {
28 | if(isset($args['id']))
29 | {
30 | return User::where('id' , $args['id'])->get();
31 | }
32 | else if(isset($args['email']))
33 | {
34 | return User::where('email', $args['email'])->get();
35 | }
36 | else
37 | {
38 | return User::all();
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Type/CommentType.php:
--------------------------------------------------------------------------------
1 | 'Comment',
10 | 'description' => 'A Comment'
11 | ];
12 |
13 | public function fields()
14 | {
15 | return [
16 | 'id' => [
17 | 'type' => Type::nonNull(Type::string()),
18 | 'description' => 'The id of the comment'
19 | ],
20 | 'body' => [
21 | 'type' => Type::nonNull(Type::string()),
22 | 'description' => 'The body of the comment'
23 | ],
24 | 'user' => \App\GraphQL\Query\UserQuery::class,
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Type/PostType.php:
--------------------------------------------------------------------------------
1 | 'Post',
10 | 'description' => 'A post'
11 | ];
12 |
13 | public function fields()
14 | {
15 | return [
16 | 'id' => [
17 | 'type' => Type::nonNull(Type::string()),
18 | 'description' => 'The id of the post'
19 | ],
20 | 'title' => [
21 | 'type' => Type::nonNull(Type::string()),
22 | 'description' => 'The title of the post'
23 | ],
24 | 'body' => [
25 | 'type' => Type::nonNull(Type::string()),
26 | 'description' => 'The body of the post'
27 | ],
28 | 'user' => \App\GraphQL\Query\UserQuery::class,
29 | 'comments' => \App\GraphQL\Query\CommentsQuery::class,
30 | ];
31 | }
32 |
33 | public function resolve($root, $args, ResolveInfo $info)
34 | {
35 | $posts = User::query();
36 |
37 | $posts->with('user', 'comments');
38 |
39 | return $posts->get();
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/Type/UserType.php:
--------------------------------------------------------------------------------
1 | 'User',
11 | 'description' => 'A user'
12 | ];
13 |
14 | public function fields()
15 | {
16 | return [
17 | 'id' => [
18 | 'type' => Type::nonNull(Type::string()),
19 | 'description' => 'The id of the user'
20 | ],
21 | 'first_name' => [
22 | 'type' => Type::nonNull(Type::string()),
23 | 'description' => 'The first name of the user'
24 | ],
25 | 'last_name' => [
26 | 'type' => Type::nonNull(Type::string()),
27 | 'description' => 'The last name of the user'
28 | ],
29 | 'email' => [
30 | 'type' => Type::string(),
31 | 'description' => 'The email of user'
32 | ],
33 | 'username' => [
34 | 'type' => Type::nonNull(Type::string()),
35 | 'description' => 'The username of the user'
36 | ],
37 | ];
38 | }
39 |
40 | protected function resolveEmailField($root, $args)
41 | {
42 | return strtolower($root->email);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/GraphQL/mutation/UpdateUserPasswordMutation.php:
--------------------------------------------------------------------------------
1 | 'UpdateUserPassword'
12 | ];
13 |
14 | public function type()
15 | {
16 | return GraphQL::type('user');
17 | }
18 |
19 | public function args()
20 | {
21 | return [
22 | 'id' => ['name' => 'id', 'type' => Type::nonNull(Type::string())],
23 | 'password' => ['name' => 'password', 'type' => Type::nonNull(Type::string())]
24 | ];
25 | }
26 |
27 | public function resolve($root, $args)
28 | {
29 | $user = User::find($args['id']);
30 | if(!$user)
31 | {
32 | return null;
33 | }
34 |
35 | $user->password = bcrypt($args['password']);
36 | $user->save();
37 | return $user;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Http/Controllers/Auth/PasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | $token]);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Http/Middleware/Authenticate.php:
--------------------------------------------------------------------------------
1 | guest()) {
21 | if ($request->ajax() || $request->wantsJson()) {
22 | return response('Unauthorized.', 401);
23 | } else {
24 | return redirect()->guest('login');
25 | }
26 | }
27 |
28 | return $next($request);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Http/Middleware/EncryptCookies.php:
--------------------------------------------------------------------------------
1 | check()) {
21 | return redirect('/');
22 | }
23 |
24 | return $next($request);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Http/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 | 'graphql.query',
18 | 'uses' => '\Folklore\GraphQL\GraphQLController@query'
19 | ))->middleware(['jwt.auth']);
20 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Jobs/Job.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\User');
21 | }
22 |
23 | public function comments()
24 | {
25 | return $this->hasMany('App\Comment');
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Providers/AppServiceProvider.php:
--------------------------------------------------------------------------------
1 | 'App\Policies\ModelPolicy',
17 | ];
18 |
19 | /**
20 | * Register any application authentication / authorization services.
21 | *
22 | * @param \Illuminate\Contracts\Auth\Access\Gate $gate
23 | * @return void
24 | */
25 | public function boot(GateContract $gate)
26 | {
27 | $this->registerPolicies($gate);
28 |
29 | //
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/Providers/EventServiceProvider.php:
--------------------------------------------------------------------------------
1 | [
17 | 'App\Listeners\EventListener',
18 | ],
19 | ];
20 |
21 | /**
22 | * Register any other events for your application.
23 | *
24 | * @param \Illuminate\Contracts\Events\Dispatcher $events
25 | * @return void
26 | */
27 | public function boot(DispatcherContract $events)
28 | {
29 | parent::boot($events);
30 |
31 | //
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/php/laravel_graphql/app/User.php:
--------------------------------------------------------------------------------
1 | hasMany('App\Comment');
30 | }
31 |
32 | public function posts()
33 | {
34 | return $this->hasMany('App\Post');
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/php/laravel_graphql/bootstrap/autoload.php:
--------------------------------------------------------------------------------
1 | [
17 | //
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled File Providers
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may list service providers which define a "compiles" function
26 | | that returns additional files that should be compiled, providing an
27 | | easy way to get common files from any packages you are utilizing.
28 | |
29 | */
30 |
31 | 'providers' => [
32 | //
33 | ],
34 |
35 | ];
36 |
--------------------------------------------------------------------------------
/php/laravel_graphql/config/services.php:
--------------------------------------------------------------------------------
1 | [
18 | 'domain' => env('MAILGUN_DOMAIN'),
19 | 'secret' => env('MAILGUN_SECRET'),
20 | ],
21 |
22 | 'ses' => [
23 | 'key' => env('SES_KEY'),
24 | 'secret' => env('SES_SECRET'),
25 | 'region' => 'us-east-1',
26 | ],
27 |
28 | 'sparkpost' => [
29 | 'secret' => env('SPARKPOST_SECRET'),
30 | ],
31 |
32 | 'stripe' => [
33 | 'model' => App\User::class,
34 | 'key' => env('STRIPE_KEY'),
35 | 'secret' => env('STRIPE_SECRET'),
36 | ],
37 |
38 | ];
39 |
--------------------------------------------------------------------------------
/php/laravel_graphql/config/view.php:
--------------------------------------------------------------------------------
1 | [
17 | realpath(base_path('resources/views')),
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled View Path
23 | |--------------------------------------------------------------------------
24 | |
25 | | This option determines where all the compiled Blade templates will be
26 | | stored for your application. Typically, this is within the storage
27 | | directory. However, as usual, you are free to change this value.
28 | |
29 | */
30 |
31 | 'compiled' => realpath(storage_path('framework/views')),
32 |
33 | ];
34 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('name');
18 | $table->string('first_name');
19 | $table->string('last_name');
20 | $table->string('username')->unique();
21 | $table->string('email')->unique();
22 | $table->string('password');
23 | $table->rememberToken();
24 | $table->timestamps();
25 | });
26 | }
27 |
28 | /**
29 | * Reverse the migrations.
30 | *
31 | * @return void
32 | */
33 | public function down()
34 | {
35 | Schema::drop('users');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/migrations/2014_10_12_100000_create_password_resets_table.php:
--------------------------------------------------------------------------------
1 | string('email')->index();
17 | $table->string('token')->index();
18 | $table->timestamp('created_at');
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | *
25 | * @return void
26 | */
27 | public function down()
28 | {
29 | Schema::drop('password_resets');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/migrations/2016_05_31_071858_create_posts_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('title');
18 | $table->longText('body');
19 | $table->integer('user_id');
20 | $table->foreign('user_id')->references('id')->on('users');
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::drop('posts');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/migrations/2016_05_31_071904_create_comments_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->longText('body');
18 | $table->integer('user_id');
19 | $table->integer('post_id');
20 | $table->foreign('user_id')->references('id')->on('users');
21 | $table->foreign('post_id')->references('id')->on('posts');
22 | $table->timestamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | *
29 | * @return void
30 | */
31 | public function down()
32 | {
33 | Schema::drop('comments');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/seeds/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/seeds/CommentsTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/seeds/DatabaseSeeder.php:
--------------------------------------------------------------------------------
1 | call(UsersTableSeeder::class);
15 | $this->call(PostsTableSeeder::class);
16 | $this->call(CommentsTableSeeder::class);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/seeds/PostsTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/php/laravel_graphql/database/seeds/UsersTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/php/laravel_graphql/gulpfile.js:
--------------------------------------------------------------------------------
1 | var elixir = require('laravel-elixir');
2 |
3 | /*
4 | |--------------------------------------------------------------------------
5 | | Elixir Asset Management
6 | |--------------------------------------------------------------------------
7 | |
8 | | Elixir provides a clean, fluent API for defining some basic Gulp tasks
9 | | for your Laravel application. By default, we are compiling the Sass
10 | | file for our application, as well as publishing vendor resources.
11 | |
12 | */
13 |
14 | elixir(function(mix) {
15 | mix.sass('app.scss');
16 | });
17 |
--------------------------------------------------------------------------------
/php/laravel_graphql/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "prod": "gulp --production",
5 | "dev": "gulp watch"
6 | },
7 | "devDependencies": {
8 | "gulp": "^3.9.1",
9 | "laravel-elixir": "^5.0.0",
10 | "bootstrap-sass": "^3.0.0"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/php/laravel_graphql/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests
14 |
15 |
16 |
17 |
18 | ./app
19 |
20 | ./app/Http/routes.php
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/php/laravel_graphql/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Redirect Trailing Slashes If Not A Folder...
9 | RewriteCond %{REQUEST_FILENAME} !-d
10 | RewriteRule ^(.*)/$ /$1 [L,R=301]
11 |
12 | # Handle Front Controller...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_FILENAME} !-f
15 | RewriteRule ^ index.php [L]
16 |
17 | # Handle Authorization Header
18 | RewriteCond %{HTTP:Authorization} .
19 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
20 |
21 |
--------------------------------------------------------------------------------
/php/laravel_graphql/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/php/laravel_graphql/public/favicon.ico
--------------------------------------------------------------------------------
/php/laravel_graphql/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/php/laravel_graphql/public/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/php/laravel_graphql/readme.md:
--------------------------------------------------------------------------------
1 | # Laravel Graphql Server
2 |
3 | ### Running locally
4 |
5 | ``` bash
6 | git clone repo
7 | cd repo
8 | createdb laravel_graphql
9 | php artisan migrate
10 | php artisan db:seed
11 | php artisan serve
12 | ```
13 | [Visit browser](http://localhost:8000/)
14 |
15 | # Features
16 | * Graphql API
17 | * CSRF and SESSION
18 | * TOKEN AUTH
19 |
20 | ### Supported API queries
21 |
22 | ```
23 | {
24 | posts {
25 | id,
26 | title,
27 | body,
28 | comments {
29 | id,
30 | body
31 | }
32 | user {
33 | id,
34 | first_name
35 | }
36 | }
37 | }
38 | ```
39 | ```
40 | {
41 | posts(id: 1) {
42 | id,
43 | title,
44 | body,
45 | comments {
46 | id,
47 | body
48 | }
49 | user {
50 | id,
51 | first_name
52 | }
53 | }
54 | }
55 | ```
56 |
57 | ```
58 | {
59 | posts(id: 1) {
60 | id,
61 | title,
62 | body,
63 | comments {
64 | id,
65 | body
66 | user {
67 | id
68 | first_name
69 | }
70 | }
71 | user {
72 | id,
73 | first_name
74 | }
75 | }
76 | }
77 | ```
78 |
--------------------------------------------------------------------------------
/php/laravel_graphql/resources/assets/sass/app.scss:
--------------------------------------------------------------------------------
1 | // @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
2 |
3 |
--------------------------------------------------------------------------------
/php/laravel_graphql/resources/lang/en/auth.php:
--------------------------------------------------------------------------------
1 | 'These credentials do not match our records.',
17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/php/laravel_graphql/resources/lang/en/pagination.php:
--------------------------------------------------------------------------------
1 | '« Previous',
17 | 'next' => 'Next »',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/php/laravel_graphql/resources/lang/en/passwords.php:
--------------------------------------------------------------------------------
1 | 'Passwords must be at least six characters and match the confirmation.',
17 | 'reset' => 'Your password has been reset!',
18 | 'sent' => 'We have e-mailed your password reset link!',
19 | 'token' => 'This password reset token is invalid.',
20 | 'user' => "We can't find a user with that e-mail address.",
21 |
22 | ];
23 |
--------------------------------------------------------------------------------
/php/laravel_graphql/resources/views/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/php/laravel_graphql/server.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 |
10 | $uri = urldecode(
11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
12 | );
13 |
14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the
15 | // built-in PHP web server. This provides a convenient way to test a Laravel
16 | // application without having installed a "real" web server software here.
17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
18 | return false;
19 | }
20 |
21 | require_once __DIR__.'/public/index.php';
22 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !public/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/app/public/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/framework/.gitignore:
--------------------------------------------------------------------------------
1 | config.php
2 | routes.php
3 | schedule-*
4 | compiled.php
5 | services.json
6 | events.scanned.php
7 | routes.scanned.php
8 | down
9 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/framework/sessions/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/php/laravel_graphql/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/python/README.md:
--------------------------------------------------------------------------------
1 | # Python based web frameworks
2 |
3 | A set of GraphQL server implementation on popular Python web frameworks.
4 |
5 | Make sure `Python >= 3.5` and `pip` is installed on your machine.
6 |
7 | ``` bash
8 | $ brew update
9 | $ brew install pyenv
10 | $ pyenv install 3.5.1
11 | $ sudo easy_install pip
12 | $ pyenv local 3.5.1 # Setup locally as standard python version
13 | ```
14 |
15 | Then, follow the example readme to setup application locally.
16 |
--------------------------------------------------------------------------------
/python/django_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Flask Graphql
2 |
3 | Make sure `Python >= 3.5` and `pip` is installed on your machine.
4 |
5 | ```bash
6 | git clone repo
7 | cd folder
8 | sudo -H pip install -r requirements.md
9 | python ./manage.py loaddata seed
10 | python manage.py runserver
11 | ```
12 |
13 | [Visit browser](http://127.0.0.1:8000/)
14 |
15 | ### Supported API Queries
16 |
17 | ```
18 | {
19 | allPosts {
20 | id,
21 | title
22 | body
23 | user {
24 | id
25 | firstName
26 | }
27 | comments{
28 | id
29 | body
30 | user{
31 | id
32 | firstName
33 | }
34 | }
35 |
36 | }
37 | }
38 | ```
39 |
40 | ```
41 | {
42 | post(id: 1) {
43 | id,
44 | title
45 | body
46 | user {
47 | id
48 | firstName
49 | }
50 | comments{
51 | id
52 | body
53 | user{
54 | id
55 | firstName
56 | }
57 | }
58 |
59 | }
60 | }
61 | ```
62 |
63 | ```
64 | {
65 | user(id: 1) {
66 | id,
67 | firstName
68 | posts{
69 | id
70 | body
71 | user{
72 | id
73 | firstName
74 | }
75 | }
76 |
77 | }
78 | }
79 | ```
80 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/__init__.py
--------------------------------------------------------------------------------
/python/django_graphql/blog/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/__init__.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/admin.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/admin.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/apps.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.apps import AppConfig
4 |
5 |
6 | class BlogConfig(AppConfig):
7 | name = 'blog'
8 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/migrations/0001_initial.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/migrations/0001_initial.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/migrations/__init__.py
--------------------------------------------------------------------------------
/python/django_graphql/blog/migrations/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/migrations/__init__.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/models.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.db import models
4 | from django.contrib.auth.models import User
5 |
6 |
7 | class Post(models.Model):
8 | user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
9 | title = models.CharField(max_length=200)
10 | body = models.CharField(max_length=200)
11 | published_date = models.DateTimeField('date published')
12 |
13 | class Comment(models.Model):
14 | user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')
15 | post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
16 | body = models.CharField(max_length=200)
17 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/models.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/models.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/schema.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/schema.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 | from . import views
4 |
5 | urlpatterns = [
6 | url(r'^$', views.index, name='index'),
7 | ]
8 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/urls.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/urls.pyc
--------------------------------------------------------------------------------
/python/django_graphql/blog/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | from django.http import HttpResponse
4 |
5 | def index(request):
6 | return HttpResponse("Hello, world. You're at the blog index.")
7 |
--------------------------------------------------------------------------------
/python/django_graphql/blog/views.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/blog/views.pyc
--------------------------------------------------------------------------------
/python/django_graphql/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/db.sqlite3
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/django_graphql/__init__.py
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/django_graphql/__init__.pyc
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/schema.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/django_graphql/schema.pyc
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/settings.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/django_graphql/settings.pyc
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/urls.py:
--------------------------------------------------------------------------------
1 | """django_graphql URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/1.9/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.conf.urls import url, include
14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 | """
16 | from django.conf.urls import include, url
17 | from django.contrib import admin
18 | from django.views.decorators.csrf import csrf_exempt
19 |
20 | from graphene.contrib.django.views import GraphQLView
21 |
22 | from django_graphql.schema import schema
23 |
24 | urlpatterns = [
25 | url(r'^graphql', csrf_exempt(GraphQLView.as_view(schema=schema))),
26 | url(r'^blog/', include('blog.urls')),
27 | url(r'^admin/', admin.site.urls),
28 | url(r'^', include('django_graphiql.urls')),
29 | ]
30 |
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/urls.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/django_graphql/urls.pyc
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for django_graphql project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_graphql.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/python/django_graphql/django_graphql/wsgi.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/django_graphql/django_graphql/wsgi.pyc
--------------------------------------------------------------------------------
/python/django_graphql/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_graphql.settings")
7 |
8 | from django.core.management import execute_from_command_line
9 |
10 | execute_from_command_line(sys.argv)
11 |
--------------------------------------------------------------------------------
/python/django_graphql/requirements.txt:
--------------------------------------------------------------------------------
1 | django>=1.9
2 | graphene[django]
3 | django_graphiql
4 | django-filter
5 |
--------------------------------------------------------------------------------
/python/flask_graphql/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/__init__.py
--------------------------------------------------------------------------------
/python/flask_graphql/app.py:
--------------------------------------------------------------------------------
1 | from schema import schema
2 | from models import app
3 | from flask_graphql import GraphQLView
4 |
5 | app.add_url_rule('/', view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True))
6 |
7 | if __name__ == '__main__':
8 | app.run()
9 |
--------------------------------------------------------------------------------
/python/flask_graphql/app.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/app.pyc
--------------------------------------------------------------------------------
/python/flask_graphql/config.py:
--------------------------------------------------------------------------------
1 | import os
2 | basedir = os.path.abspath(os.path.dirname(__file__))
3 |
4 |
5 | class Config(object):
6 | DEBUG = False
7 | TESTING = False
8 | CSRF_ENABLED = True
9 | SECRET_KEY = 'some-secret-key'
10 | SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']
11 |
12 |
13 | class ProductionConfig(Config):
14 | DEBUG = False
15 |
16 |
17 | class StagingConfig(Config):
18 | DEVELOPMENT = True
19 | DEBUG = True
20 |
21 |
22 | class DevelopmentConfig(Config):
23 | DEVELOPMENT = True
24 | DEBUG = True
25 |
26 |
27 | class TestingConfig(Config):
28 | TESTING = True
29 |
--------------------------------------------------------------------------------
/python/flask_graphql/config.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/config.pyc
--------------------------------------------------------------------------------
/python/flask_graphql/manage.py:
--------------------------------------------------------------------------------
1 | import os
2 | from flask.ext.script import Manager
3 | from flask.ext.migrate import Migrate, MigrateCommand
4 |
5 | from models import app, db
6 |
7 |
8 | app.config.from_object(os.environ['APP_SETTINGS'])
9 |
10 | migrate = Migrate(app, db)
11 | manager = Manager(app)
12 |
13 | manager.add_command('db', MigrateCommand)
14 |
15 |
16 | if __name__ == '__main__':
17 | manager.run()
18 |
--------------------------------------------------------------------------------
/python/flask_graphql/migrations/README:
--------------------------------------------------------------------------------
1 | Generic single-database configuration.
--------------------------------------------------------------------------------
/python/flask_graphql/migrations/alembic.ini:
--------------------------------------------------------------------------------
1 | # A generic, single database configuration.
2 |
3 | [alembic]
4 | # template used to generate migration files
5 | # file_template = %%(rev)s_%%(slug)s
6 |
7 | # set to 'true' to run the environment during
8 | # the 'revision' command, regardless of autogenerate
9 | # revision_environment = false
10 |
11 |
12 | # Logging configuration
13 | [loggers]
14 | keys = root,sqlalchemy,alembic
15 |
16 | [handlers]
17 | keys = console
18 |
19 | [formatters]
20 | keys = generic
21 |
22 | [logger_root]
23 | level = WARN
24 | handlers = console
25 | qualname =
26 |
27 | [logger_sqlalchemy]
28 | level = WARN
29 | handlers =
30 | qualname = sqlalchemy.engine
31 |
32 | [logger_alembic]
33 | level = INFO
34 | handlers =
35 | qualname = alembic
36 |
37 | [handler_console]
38 | class = StreamHandler
39 | args = (sys.stderr,)
40 | level = NOTSET
41 | formatter = generic
42 |
43 | [formatter_generic]
44 | format = %(levelname)-5.5s [%(name)s] %(message)s
45 | datefmt = %H:%M:%S
46 |
--------------------------------------------------------------------------------
/python/flask_graphql/migrations/env.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/migrations/env.pyc
--------------------------------------------------------------------------------
/python/flask_graphql/migrations/script.py.mako:
--------------------------------------------------------------------------------
1 | """${message}
2 |
3 | Revision ID: ${up_revision}
4 | Revises: ${down_revision}
5 | Create Date: ${create_date}
6 |
7 | """
8 |
9 | # revision identifiers, used by Alembic.
10 | revision = ${repr(up_revision)}
11 | down_revision = ${repr(down_revision)}
12 |
13 | from alembic import op
14 | import sqlalchemy as sa
15 | ${imports if imports else ""}
16 |
17 | def upgrade():
18 | ${upgrades if upgrades else "pass"}
19 |
20 |
21 | def downgrade():
22 | ${downgrades if downgrades else "pass"}
23 |
--------------------------------------------------------------------------------
/python/flask_graphql/migrations/versions/11261ac968e5_.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/migrations/versions/11261ac968e5_.pyc
--------------------------------------------------------------------------------
/python/flask_graphql/models.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/models.pyc
--------------------------------------------------------------------------------
/python/flask_graphql/requirements.txt:
--------------------------------------------------------------------------------
1 | graphene[sqlalchemy]
2 | SQLAlchemy==1.0.11
3 | Flask==0.10.1
4 | Flask-GraphQL==1.3.0
5 | Flask-Migrate==1.8.0
6 | psycopg2==2.6.1
7 |
--------------------------------------------------------------------------------
/python/flask_graphql/schema.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/python/flask_graphql/schema.pyc
--------------------------------------------------------------------------------
/python/flask_graphql/seed.py:
--------------------------------------------------------------------------------
1 | from models import db
2 | from models import Post
3 | from models import Comment
4 | from models import User
5 |
6 | db.create_all()
7 |
8 | john = User(first_name='John', last_name='Doe', email="john@doe.com", username="johndoe")
9 | maggie = User(first_name='Maggie', last_name='Turner', email="maggie@turner.com", username="maggie")
10 |
11 | db.session.add(john)
12 | db.session.add(maggie)
13 |
14 | post1 = Post(title="First post title", body="First post body", user_id=1)
15 | post2 = Post(title="Second post title", body="Second post body", user_id=2)
16 |
17 | comment1 = Comment(body="first post comment", user_id=1, post_id=1)
18 | comment2 = Comment(body="second post comment", user_id=2, post_id=2)
19 |
20 | db.session.add(post1)
21 | db.session.add(post2)
22 | db.session.add(comment1)
23 | db.session.add(comment2)
24 | db.session.commit()
25 |
--------------------------------------------------------------------------------
/ruby/README.md:
--------------------------------------------------------------------------------
1 | # Ruby based web frameworks
2 |
3 | A set of GraphQL server implementation on popular ruby web frameworks.
4 |
5 | ## Frameworks
6 | * Rails
7 | * Sinatra
8 | * Roda
9 | * Cuba
10 |
11 | ```bash
12 | $ brew update
13 | $ brew install rbenv
14 | # list all available versions:
15 | $ rbenv install -l
16 |
17 | # install a Ruby version:
18 | $ rbenv install 2.3.1
19 | ```
20 |
21 | Then, follow the example readme to setup application locally.
22 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/.bundle/config:
--------------------------------------------------------------------------------
1 | ---
2 | BUNDLE_DISABLE_SHARED_GEMS: true
3 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle
2 | vendor/bundle
3 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/Gemfile:
--------------------------------------------------------------------------------
1 |
2 | source "https://rubygems.org"
3 |
4 | gem 'cuba'
5 | gem 'puma'
6 | gem 'data_mapper'
7 | gem 'graphql'
8 | gem 'tilt'
9 | gem 'json'
10 | gem 'dm-postgres-adapter'
11 | gem 'rack-protection'
12 |
13 | # Token
14 | gem 'rack-jwt'
15 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/README.md:
--------------------------------------------------------------------------------
1 | # Sinatra Graphql Server
2 |
3 | ### Setup and Running locally
4 |
5 | ```bash
6 | git clone repo
7 | cd to folder
8 | bundle install
9 | # make sure postgres is installed
10 | createdb sinatra_graphql_development
11 | bundle exec rake db:migrate
12 | bundle exec rake db:seed
13 | # run the server
14 | bundle exec rackup -p 3000
15 | # Visit http://localhost:3000
16 | ```
17 |
18 | [Visit browser](http://localhost:3000)
19 |
20 | # Features
21 | * Graphql API
22 | * CSRF and SESSION
23 | * TOKEN AUTH
24 |
25 | ### Supported API Queries
26 | ```
27 | {
28 | all_posts {
29 | id,
30 | title,
31 | body,
32 | user {
33 | id,
34 | first_name
35 | }
36 | comments {
37 | id,
38 | body
39 | user {
40 | id,
41 | first_name
42 | }
43 | }
44 |
45 | }
46 | }
47 | ```
48 |
49 | ```
50 | {
51 | post(id: 2) {
52 | id,
53 | title,
54 | body,
55 | user {
56 | id,
57 | first_name
58 | }
59 | comments {
60 | id,
61 | body
62 | user {
63 | id,
64 | first_name
65 | }
66 | }
67 |
68 | }
69 | }
70 | ```
71 |
72 | ### DB
73 | * Postgresql (with ruby Sequel ORM)
74 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/api/schema.rb:
--------------------------------------------------------------------------------
1 | require_relative 'types/post_type'
2 | QueryType = GraphQL::ObjectType.define do
3 | name "Query"
4 | description "The query root of this schema"
5 |
6 | field :post do
7 | type PostType
8 | argument :id, !types.ID
9 | resolve -> (obj, args, ctx) { Post.get(args["id"]) }
10 | end
11 |
12 | field :all_posts do
13 | type types[!PostType]
14 | resolve -> (obj, args, ctx) { Post.all }
15 | end
16 | end
17 |
18 | Schema = GraphQL::Schema.new(query: QueryType)
19 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/api/types/comment_type.rb:
--------------------------------------------------------------------------------
1 | CommentType = GraphQL::ObjectType.define do
2 | name "Comment"
3 | description "A comment"
4 |
5 | field :id, !types.ID
6 | field :body, !types.String
7 | field :user, -> { UserType }
8 | field :post, -> { PostType }
9 | end
10 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/api/types/post_type.rb:
--------------------------------------------------------------------------------
1 | PostType = GraphQL::ObjectType.define do
2 | name "Post"
3 | description "A post"
4 |
5 | field :id, !types.ID
6 | field :title, !types.String
7 | field :body, !types.String
8 | field :user, -> { UserType }
9 | field :comments, -> { types[!CommentType] }
10 | end
11 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/api/types/user_type.rb:
--------------------------------------------------------------------------------
1 | UserType = GraphQL::ObjectType.define do
2 | name "User"
3 | description "A user"
4 |
5 | field :id, !types.ID
6 | field :first_name, !types.String
7 | field :last_name, !types.String
8 | field :username, !types.String
9 | field :email, !types.String
10 | field :posts, -> { types[!PostType] }
11 | field :comments, -> { types[!CommentType] }
12 | end
13 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/config.ru:
--------------------------------------------------------------------------------
1 | $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
2 | require 'bundler'
3 | Bundler.require
4 | require 'cuba/render'
5 | require 'tilt/erb'
6 |
7 | Cuba.plugin Cuba::Render
8 | DataMapper::Logger.new(STDOUT, :debug, '[DataMapper] ')
9 |
10 | # Local config
11 | require "find"
12 |
13 | %w{api api/types middlewares}.each do |load_path|
14 | Find.find(load_path) { |f|
15 | require f unless f.match(/\/\..+$/) || File.directory?(f)
16 | }
17 | end
18 |
19 | require "./cuba_grapgql"
20 | run Cuba
21 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/cuba_grapgql.rb:
--------------------------------------------------------------------------------
1 | require 'rack/protection'
2 | Cuba.use Rack::Session::Cookie, secret: 'super_secret_key'
3 | Cuba.use Rack::Protection
4 | Cuba.use Rack::Protection::RemoteReferrer
5 | # Use middleware for demo (use authentication in real app)
6 | Cuba.use PassAuthToken
7 | # Verify token
8 | Cuba.use Rack::JWT::Auth, {secret: 'super_secret_key', options: { algorithm: 'HS256' }}
9 |
10 | Cuba.define do
11 | # Pass token to the view
12 | data = {user_id: 1}
13 | token = Rack::JWT::Token.encode(data, 'super_secret_key', 'HS256')
14 |
15 | on get do
16 | on root do
17 | res.write view("graphiql", token: token)
18 | end
19 | end
20 |
21 | on post do
22 | on "graphql" do
23 | params = JSON.parse(req.body.read)
24 | payload = Schema.execute(
25 | params["query"],
26 | variables: params["variables"]
27 | ).to_json
28 |
29 | res.headers["Content-Type"] = "application/json; charset=utf-8"
30 | res.write payload
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/ruby/cuba_grapgql/middlewares/pass_auth_token.rb:
--------------------------------------------------------------------------------
1 | # Inject authorization token for root route
2 | # Because we don't have it
3 | # For real app you would use generally some kind of authentication
4 |
5 | class PassAuthToken
6 | def initialize(app)
7 | @app = app
8 | end
9 |
10 | def call(env)
11 | data = {user_id: 1} # Anything you want to encode
12 | token = Rack::JWT::Token.encode(data, 'super_secret_key', 'HS256')
13 | if env['REQUEST_PATH'] == '/'
14 | env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
15 | end
16 | @app.call(env)
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore all logfiles and tempfiles.
11 | /log/*
12 | /tmp/*
13 | !/log/.keep
14 | !/tmp/.keep
15 |
16 | # Ignore Byebug command history file.
17 | .byebug_history
18 |
19 | vendor/bundle
20 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
3 | gem 'rails', '>= 5.0.0.rc1', '< 5.1'
4 | # Use postgresql as the database for Active Record
5 | gem 'pg', '~> 0.18'
6 | # Use Puma as the app server
7 | gem 'puma', '~> 3.0'
8 | # gem 'bcrypt', '~> 3.1.7'
9 | gem 'sprockets-rails'
10 | gem 'sass-rails'
11 | gem 'uglifier'
12 | gem 'graphql'
13 | gem 'graphql-relay'
14 | gem 'graphiql-rails'
15 |
16 | # Token auth
17 | gem 'rack-jwt'
18 |
19 | group :development, :test do
20 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console
21 | gem 'byebug', platform: :mri
22 | end
23 |
24 | group :development do
25 | gem 'listen', '~> 3.0.5'
26 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
27 | gem 'spring'
28 | gem 'spring-watcher-listen', '~> 2.0.0'
29 | end
30 |
31 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
32 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
33 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Rails Graphql Server
2 |
3 | ### Setup and Running locally
4 |
5 | ```bash
6 | git clone repo
7 | cd to folder
8 | bundle install
9 | # make sure postgres is installed
10 | bundle exec rake db:create db:migrate
11 | bundle exec rake db:seed
12 | # run the server
13 | bundle exec rails s
14 | # Visit http://localhost:3000/
15 | ```
16 |
17 | [Visit browser](http://localhost:3000)
18 |
19 | # Features
20 | * Graphql API
21 | * CSRF and SESSION
22 | * TOKEN AUTH
23 |
24 | ### Supported API Queries
25 | ```
26 | {
27 | all_posts {
28 | id,
29 | title,
30 | body,
31 | user {
32 | id,
33 | first_name
34 | }
35 | comments {
36 | id,
37 | body
38 | user {
39 | id,
40 | first_name
41 | }
42 | }
43 |
44 | }
45 | }
46 | ```
47 |
48 | ```
49 | {
50 | post(id: 2) {
51 | id,
52 | title,
53 | body,
54 | user {
55 | id,
56 | first_name
57 | }
58 | comments {
59 | id,
60 | body
61 | user {
62 | id,
63 | first_name
64 | }
65 | }
66 |
67 | }
68 | }
69 | ```
70 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require_relative 'config/application'
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/api/node_identification.rb:
--------------------------------------------------------------------------------
1 | GraphQL::Relay::GlobalNodeIdentification.instance_variable_set(:@instance, nil)
2 |
3 | NodeIdentification = GraphQL::Relay::GlobalNodeIdentification.define do
4 | # Given a UUID & the query context,
5 | # return the corresponding application object
6 | object_from_id ->(id, _ctx) { resolve_object_from_id(id) }
7 | end
8 |
9 | private
10 |
11 | def resolve_object_from_id(id)
12 | # "User" -> User.find(id)
13 | type_name, id = NodeIdentification.from_global_id(id)
14 | type_name.constantize.find(id)
15 | end
16 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/api/schema.rb:
--------------------------------------------------------------------------------
1 | QueryType = GraphQL::ObjectType.define do
2 | name "Query"
3 | description "The query root of this schema"
4 | field :node, field: NodeIdentification.field
5 |
6 | field :post do
7 | type PostType
8 | argument :id, !types.ID
9 | resolve -> (obj, args, ctx) { Post.includes(:user, :comments).find(args["id"]) }
10 | end
11 |
12 | field :all_posts do
13 | type types[!PostType]
14 | resolve -> (obj, args, ctx) { Post.all.includes(:user, :comments) }
15 | end
16 | end
17 |
18 | Schema = GraphQL::Schema.define do
19 | query QueryType
20 | rescue_from(ActiveRecord::RecordInvalid) do |_error|
21 | 'Some data could not be saved'
22 | end
23 |
24 | rescue_from(ActiveRecord::RecordNotFound) do |_error|
25 | 'Could not find the record'
26 | end
27 |
28 | resolve_type -> (object, _ctx) { Schema.types[type_name(object)] }
29 | node_identification NodeIdentification
30 | end
31 |
32 | def type_name(object)
33 | object.class.name
34 | end
35 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/api/types/comment_type.rb:
--------------------------------------------------------------------------------
1 | CommentType = GraphQL::ObjectType.define do
2 | name "Comment"
3 | description "A comment"
4 |
5 | interfaces [NodeIdentification.interface]
6 | global_id_field :id
7 |
8 | field :body, !types.String
9 | field :user, -> { UserType }
10 | field :post, -> { PostType }
11 | end
12 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/api/types/post_type.rb:
--------------------------------------------------------------------------------
1 | PostType = GraphQL::ObjectType.define do
2 | name "Post"
3 | description "A post"
4 |
5 | interfaces [NodeIdentification.interface]
6 | global_id_field :id
7 |
8 | field :title, !types.String
9 | field :body, !types.String
10 | field :user, -> { UserType }
11 | field :comments do
12 | type types[!CommentType]
13 | resolve -> (obj, args, ctx) { obj.comments.includes(:user) }
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/api/types/user_type.rb:
--------------------------------------------------------------------------------
1 | UserType = GraphQL::ObjectType.define do
2 | name "User"
3 | description "A user"
4 |
5 | interfaces [NodeIdentification.interface]
6 | global_id_field :id
7 |
8 | field :first_name, !types.String
9 | field :last_name, !types.String
10 | field :username, !types.String
11 | field :email, !types.String
12 | field :posts, types[!PostType]
13 | field :comments, types[!CommentType]
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | # Prevent CSRF attacks by raising an exception.
3 | # For APIs, you may want to use :null_session instead.
4 | protect_from_forgery with: :exception
5 | end
6 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/controllers/graphql_controller.rb:
--------------------------------------------------------------------------------
1 | class GraphqlController < ApplicationController
2 | skip_before_action :verify_authenticity_token
3 |
4 | def create
5 | result = Schema.execute(
6 | params[:query],
7 | variables: params[:variables]
8 | )
9 | render json: result
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | self.abstract_class = true
3 | end
4 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/models/comment.rb:
--------------------------------------------------------------------------------
1 | class Comment < ApplicationRecord
2 | belongs_to :user
3 | belongs_to :post
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/app/models/concerns/.keep
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/models/post.rb:
--------------------------------------------------------------------------------
1 | class Post < ApplicationRecord
2 | belongs_to :user
3 | has_many :comments
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/app/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < ApplicationRecord
2 | has_many :comments
3 | has_many :posts
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path('../spring', __FILE__)
4 | rescue LoadError => e
5 | raise unless e.message.include?('spring')
6 | end
7 | APP_PATH = File.expand_path('../config/application', __dir__)
8 | require_relative '../config/boot'
9 | require 'rails/commands'
10 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path('../spring', __FILE__)
4 | rescue LoadError => e
5 | raise unless e.message.include?('spring')
6 | end
7 | require_relative '../config/boot'
8 | require 'rake'
9 | Rake.application.run
10 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 | require 'fileutils'
4 | include FileUtils
5 |
6 | # path to your application root.
7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
8 |
9 | def system!(*args)
10 | system(*args) || abort("\n== Command #{args} failed ==")
11 | end
12 |
13 | chdir APP_ROOT do
14 | # This script is a starting point to setup your application.
15 | # Add necessary setup steps to this file.
16 |
17 | puts '== Installing dependencies =='
18 | system! 'gem install bundler --conservative'
19 | system('bundle check') || system!('bundle install')
20 |
21 | # puts "\n== Copying sample files =="
22 | # unless File.exist?('config/database.yml')
23 | # cp 'config/database.yml.sample', 'config/database.yml'
24 | # end
25 |
26 | puts "\n== Preparing database =="
27 | system! 'bin/rails db:setup'
28 |
29 | puts "\n== Removing old logs and tempfiles =="
30 | system! 'bin/rails log:clear tmp:clear'
31 |
32 | puts "\n== Restarting application server =="
33 | system! 'bin/rails restart'
34 | end
35 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/bin/spring:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # This file loads spring without using Bundler, in order to be fast.
4 | # It gets overwritten when you run the `spring binstub` command.
5 |
6 | unless defined?(Spring)
7 | require 'rubygems'
8 | require 'bundler'
9 |
10 | if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m))
11 | Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(Gem.path_separator) }
12 | gem 'spring', match[1]
13 | require 'spring/binstub'
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/bin/update:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 | require 'fileutils'
4 | include FileUtils
5 |
6 | # path to your application root.
7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
8 |
9 | def system!(*args)
10 | system(*args) || abort("\n== Command #{args} failed ==")
11 | end
12 |
13 | chdir APP_ROOT do
14 | # This script is a way to update your development environment automatically.
15 | # Add necessary update steps to this file.
16 |
17 | puts '== Installing dependencies =='
18 | system! 'gem install bundler --conservative'
19 | system('bundle check') || system!('bundle install')
20 |
21 | puts "\n== Updating database =="
22 | system! 'bin/rails db:migrate'
23 |
24 | puts "\n== Removing old logs and tempfiles =="
25 | system! 'bin/rails log:clear tmp:clear'
26 |
27 | puts "\n== Restarting application server =="
28 | system! 'bin/rails restart'
29 | end
30 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative 'config/environment'
4 |
5 | run Rails.application
6 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative 'application'
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/active_record_belongs_to_required_by_default.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Require `belongs_to` associations by default. This is a new Rails 5.0
4 | # default, so it is introduced as a configuration option to ensure that apps
5 | # made on earlier versions of Rails are not affected when upgrading.
6 | Rails.application.config.active_record.belongs_to_required_by_default = true
7 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # ApplicationController.renderer.defaults.merge!(
4 | # http_host: 'example.org',
5 | # https: false
6 | # )
7 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/callback_terminator.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Do not halt callback chains when a callback returns false. This is a new
4 | # Rails 5.0 default, so it is introduced as a configuration option to ensure
5 | # that apps made with earlier versions of Rails are not affected when upgrading.
6 | ActiveSupport.halt_callback_chains_on_return_false = false
7 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Specify a serializer for the signed and encrypted cookie jars.
4 | # Valid options are :json, :marshal, and :hybrid.
5 | Rails.application.config.action_dispatch.cookies_serializer = :json
6 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/graphiql.rb:
--------------------------------------------------------------------------------
1 | GraphiQL::Rails.config.query_params = false # if true, the GraphQL query string will be persisted the page's query params.
2 | GraphiQL::Rails.config.csrf = true
3 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/per_form_csrf_tokens.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Enable per-form CSRF tokens.
4 | Rails.application.config.action_controller.per_form_csrf_tokens = true
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/request_forgery_protection.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Enable origin-checking CSRF mitigation.
4 | Rails.application.config.action_controller.forgery_protection_origin_check = true
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.session_store :cookie_store, key: '_rails_graphql_session'
4 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/ssl_options.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure SSL options to enable HSTS with subdomains.
4 | Rails.application.config.ssl_options = { hsts: { subdomains: true } }
5 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/to_time_preserves_timezone.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Preserve the timezone of the receiver when calling to `to_time`.
4 | # Ruby 2.4 will change the behavior of `to_time` to preserve the timezone
5 | # when converting to an instance of `Time` instead of the previous behavior
6 | # of converting to the local system timezone.
7 | #
8 | # Rails 5.0 introduced this config option so that apps made with earlier
9 | # versions of Rails are not affected when upgrading.
10 | ActiveSupport.to_time_preserves_timezone = true
11 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more, please read the Rails Internationalization guide
20 | # available at http://guides.rubyonrails.org/i18n.html.
21 |
22 | en:
23 | hello: "Hello world"
24 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | mount GraphiQL::Rails::Engine, at: "/", graphql_path: "/graphql"
3 | scope '/graphql' do
4 | post "/", to: "graphql#create"
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/secrets.yml:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key is used for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 |
6 | # Make sure the secret is at least 30 characters and all random,
7 | # no regular words or you'll be exposed to dictionary attacks.
8 | # You can use `rails secret` to generate a secure secret key.
9 |
10 | # Make sure the secrets in this file are kept private
11 | # if you're sharing your code publicly.
12 |
13 | development:
14 | secret_key_base: 5088c07c1ef37ea7460d95a371763e53ce119cd120accbafc979272c8275c4e263859d77cf26a83c8939ebb0d035dccfa750688530bc9a545dae16a33f5561cf
15 |
16 | test:
17 | secret_key_base: 95ea85eeb501176720c4ded6625a2160b8ca31fda9ad16e9d378ff31b74b086b43efbcbd3faa0af99efc28715060e1b86befe3231bf2e57522c6aaff7b48991a
18 |
19 | # Do not keep production secrets in the repository,
20 | # instead read values from the environment.
21 | production:
22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
23 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/config/spring.rb:
--------------------------------------------------------------------------------
1 | %w(
2 | .ruby-version
3 | .rbenv-vars
4 | tmp/restart.txt
5 | tmp/caching-dev.txt
6 | ).each { |path| Spring.watch(path) }
7 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/db/migrate/20160524121108_create_users.rb:
--------------------------------------------------------------------------------
1 | class CreateUsers < ActiveRecord::Migration[5.0]
2 | def change
3 | create_table :users do |t|
4 | t.string :first_name
5 | t.string :last_name
6 | t.string :email
7 | t.string :username
8 |
9 | t.timestamps
10 | end
11 | add_index :users, :email
12 | add_index :users, :username
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/db/migrate/20160524121211_create_posts.rb:
--------------------------------------------------------------------------------
1 | class CreatePosts < ActiveRecord::Migration[5.0]
2 | def change
3 | create_table :posts do |t|
4 | t.string :title
5 | t.text :body
6 | t.references :user, foreign_key: true
7 |
8 | t.timestamps
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/db/migrate/20160524121235_create_comments.rb:
--------------------------------------------------------------------------------
1 | class CreateComments < ActiveRecord::Migration[5.0]
2 | def change
3 | create_table :comments do |t|
4 | t.text :body
5 | t.references :user, foreign_key: true
6 | t.references :post, foreign_key: true
7 |
8 | t.timestamps
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
7 | # Character.create(name: 'Luke', movie: movies.first)
8 |
9 | ActiveRecord::Base.transaction do
10 | john = User.create(first_name: 'John', last_name: 'Doe', email: 'john@doe.com', username: 'johndoe')
11 | maggie = User.create(first_name: 'Maggie', last_name: 'Turner', email: 'maggie@doe.com', username: 'maggie')
12 |
13 | 10.times do |index|
14 | Post.create(title: "This is #{index} post title", body: "This is #{index} post body", user: [john, maggie].sample)
15 | end
16 |
17 | Post.all.each do |post|
18 | 10.times do |index|
19 | Comment.create(body: "This is comment for post #{post.id}", user: [john, maggie].sample, post: post)
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/lib/assets/.keep
--------------------------------------------------------------------------------
/ruby/rails_graphql/lib/pass_auth_token.rb:
--------------------------------------------------------------------------------
1 | # Inject authorization token for root route
2 | # Because we don't have it
3 | # For real app you would use generally some kind of authentication
4 |
5 | class PassAuthToken
6 | def initialize(app)
7 | @app = app
8 | end
9 |
10 | def call(env)
11 | data = {user_id: 1} # Anything you want to encode
12 | token = Rack::JWT::Token.encode(data, 'super_secret_key', 'HS256')
13 | if env['REQUEST_PATH'] == '/'
14 | env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
15 | end
16 | @app.call(env)
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/lib/tasks/.keep
--------------------------------------------------------------------------------
/ruby/rails_graphql/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/log/.keep
--------------------------------------------------------------------------------
/ruby/rails_graphql/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/ruby/rails_graphql/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/ruby/rails_graphql/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/public/favicon.ico
--------------------------------------------------------------------------------
/ruby/rails_graphql/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/ruby/rails_graphql/tmp/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/rails_graphql/tmp/.keep
--------------------------------------------------------------------------------
/ruby/roda_graphql/.env:
--------------------------------------------------------------------------------
1 | ENVIRONMENT="development"
2 |
3 | RACK_COOKIE_KEY="roda_graphql"
4 | RACK_COOKIE_SECRET="oEwNzxGhy6Xpw81dPyVQc1GI1Tb49pn0vie+nwwHnyDBuu0IwKbcR9WoXBDTXNQAeso="
5 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle
2 | vendor/bundle
3 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | group :development do
4 | gem 'rake'
5 | end
6 |
7 | gem 'puma'
8 | gem 'roda'
9 | gem 'tilt'
10 |
11 | # Graphql
12 | gem 'graphql'
13 |
14 | # Database Stack
15 | gem 'sequel'
16 | gem 'sequel-seed'
17 | gem 'sqlite3'
18 | gem 'colorize'
19 |
20 | # Protection :)
21 | gem 'rack-protection'
22 |
23 | # Token :)
24 | gem 'rack-jwt'
25 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | colorize (0.7.7)
5 | dotenv (2.1.1)
6 | graphql (0.15.2)
7 | jwt (1.5.4)
8 | pg (0.18.4)
9 | puma (3.4.0)
10 | rack (1.6.4)
11 | rack-jwt (0.3.0)
12 | jwt (~> 1.5.2)
13 | rack (>= 1.6.0)
14 | rack-protection (1.5.3)
15 | rack
16 | rake (11.2.2)
17 | roda (2.15.0)
18 | rack
19 | sequel (4.35.0)
20 | sequel-seed (0.3.2)
21 | sequel (>= 4.0)
22 | sqlite3 (1.3.13)
23 | tilt (2.0.5)
24 |
25 | PLATFORMS
26 | ruby
27 |
28 | DEPENDENCIES
29 | colorize
30 | dotenv
31 | graphql
32 | pg
33 | puma
34 | rack-jwt
35 | rack-protection
36 | rake
37 | roda
38 | sequel
39 | sequel-seed
40 | sqlite3
41 | tilt
42 |
43 | BUNDLED WITH
44 | 1.15.3
45 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Roda Graphql Server
2 |
3 | ### Setup and Running locally
4 |
5 | ```bash
6 | git clone repo
7 | cd to folder
8 | bundle install
9 | # make sure postgres is installed
10 | createdb roda_graphql
11 | bundle exec rake db:migrate
12 | bundle exec rake db:seed
13 | # run the server
14 | bundle exec rackup -p 3000
15 | # Visit http://localhost:3000
16 | ```
17 |
18 | [Visit browser](http://localhost:3000)
19 |
20 | # Features
21 | * Graphql API
22 | * CSRF and SESSION
23 | * TOKEN AUTH
24 |
25 | ### Supported API Queries
26 | ```
27 | {
28 | all_posts {
29 | id,
30 | title,
31 | body,
32 | user {
33 | id,
34 | first_name
35 | }
36 | comments {
37 | id,
38 | body
39 | user {
40 | id,
41 | first_name
42 | }
43 | }
44 |
45 | }
46 | }
47 | ```
48 |
49 | ```
50 | {
51 | post(id: 2) {
52 | id,
53 | title,
54 | body,
55 | user {
56 | id,
57 | first_name
58 | }
59 | comments {
60 | id,
61 | body
62 | user {
63 | id,
64 | first_name
65 | }
66 | }
67 |
68 | }
69 | }
70 | ```
71 |
72 | ### DB
73 | * Postgresql (with ruby Sequel ORM)
74 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/Rakefile:
--------------------------------------------------------------------------------
1 | require 'sequel'
2 | require 'sequel/extensions/seed'
3 |
4 | namespace :db do
5 | task :environment do
6 | puts 'task environment'
7 | end
8 | desc "Run all migrations in db/migrate"
9 | task :migrate => :connect do
10 | Sequel.extension(:migration)
11 | Sequel::Migrator.apply(DB, "db/migrate")
12 | end
13 |
14 | task :seed => :connect do
15 | Sequel.extension(:seed)
16 | Sequel::Seeder.apply(DB, "db/seeds")
17 | end
18 |
19 | task :connect => :environment do
20 | DB = Sequel.connect("sqlite://blog.db")
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/models/comment.rb:
--------------------------------------------------------------------------------
1 | class Comment < Sequel::Model
2 | many_to_one :post
3 | many_to_one :user
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/models/post.rb:
--------------------------------------------------------------------------------
1 | class Post < Sequel::Model
2 | one_to_many :comments
3 | many_to_one :user
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < Sequel::Model
2 | one_to_many :comments
3 | one_to_many :posts
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/routes/main.rb:
--------------------------------------------------------------------------------
1 | class RodaGraphql
2 | route do |r|
3 | r.root do
4 | data = {user_id: 1}
5 | token = Rack::JWT::Token.encode(data, ENV['RACK_COOKIE_SECRET'], 'HS256')
6 | set_layout_locals token: token
7 | view("graphiql")
8 | end
9 |
10 | r.on "graphql" do
11 | r.post do
12 | params = JSON.parse(request.body.read)
13 | result = Schema.execute(
14 | params["query"],
15 | variables: params["variables"]
16 | )
17 |
18 | response['Content-Type'] = 'application/json; charset=utf-8'
19 | result.to_json
20 | end
21 | end
22 |
23 | r.assets
24 | r.multi_route
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/schema.rb:
--------------------------------------------------------------------------------
1 | QueryType = GraphQL::ObjectType.define do
2 | name "Query"
3 | description "The query root of this schema"
4 |
5 | field :post do
6 | type PostType
7 | argument :id, !types.ID
8 | resolve -> (obj, args, ctx) { Post.find(id: args["id"]) }
9 | end
10 |
11 | field :all_posts do
12 | type types[!PostType]
13 | resolve -> (obj, args, ctx) { Post.all }
14 | end
15 | end
16 |
17 | Schema = GraphQL::Schema.new(query: QueryType)
18 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/types/comment_type.rb:
--------------------------------------------------------------------------------
1 | CommentType = GraphQL::ObjectType.define do
2 | name "Comment"
3 | description "A comment"
4 |
5 | field :id, !types.ID
6 | field :body, !types.String
7 | field :user, -> { UserType }
8 | field :post, -> { PostType }
9 | end
10 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/types/post_type.rb:
--------------------------------------------------------------------------------
1 | PostType = GraphQL::ObjectType.define do
2 | name "Post"
3 | description "A post"
4 |
5 | field :id, !types.ID
6 | field :title, !types.String
7 | field :body, !types.String
8 | field :user, -> { UserType }
9 | field :comments, -> { types[!CommentType] }
10 | end
11 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/api/types/user_type.rb:
--------------------------------------------------------------------------------
1 | UserType = GraphQL::ObjectType.define do
2 | name "User"
3 | description "A user"
4 |
5 | field :id, !types.ID
6 | field :first_name, !types.String
7 | field :last_name, !types.String
8 | field :username, !types.String
9 | field :email, !types.String
10 | field :posts, -> { types[!PostType] }
11 | field :comments, -> { types[!CommentType] }
12 | end
13 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/assets/assets.rb:
--------------------------------------------------------------------------------
1 | class RodaGraphql < Roda
2 | def self.css_files
3 | [].tap do |css|
4 | css << "graphiql-0.7.0.css"
5 | css << "main.css"
6 | css << "application.css"
7 | end
8 | end
9 |
10 | def self.js_files
11 | [].tap do |js|
12 | js << "react-15.0.1.js"
13 | js << "react-dom-15.0.1.js"
14 | js << "fetch-0.10.1.js"
15 | js << "graphiql-0.7.0.js"
16 | end
17 | end
18 |
19 | dependencies = Hash.new(Dir["assets/" "**/*.*"])
20 |
21 | self.plugin :assets, css: css_files, js: js_files, dependencies: dependencies
22 | compile_assets if production?
23 | end
24 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/assets/css/application.css:
--------------------------------------------------------------------------------
1 |
2 | @import "graphiql-0.7.0.css";
3 | @import "main.css";
4 |
5 | html, body {
6 | height: 100%;
7 | margin: 0;
8 | overflow: hidden;
9 | width: 100%;
10 | }
11 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/assets/js/application.js:
--------------------------------------------------------------------------------
1 | //= require ./react-15.0.1
2 | //= require ./react-dom-15.0.1
3 | //= require ./fetch-0.10.1
4 | //= require ./graphiql-0.7.0
5 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/blog.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/roda_graphql/blog.db
--------------------------------------------------------------------------------
/ruby/roda_graphql/config.ru:
--------------------------------------------------------------------------------
1 | # Load path and gems/bundler
2 | $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
3 | require 'tilt/erb'
4 | require 'bundler'
5 | require 'logger'
6 | Bundler.require
7 |
8 | # Local config
9 | require "find"
10 |
11 | %w{config/initializers api/types api/models middlewares}.each do |load_path|
12 | Find.find(load_path) { |f|
13 | require f unless f.match(/\/\..+$/) || File.directory?(f)
14 | }
15 | end
16 |
17 | logger = Logger.new(STDOUT)
18 |
19 | logger.level = Logger::DEBUG
20 | logger.formatter = proc do |severity, datetime, progname, msg|
21 | date_format = datetime.strftime("%Y-%m-%d %H:%M:%S")
22 | if severity == "INFO"
23 | "[#{date_format}] #{severity} (#{progname}): #{msg}\n".blue
24 | elsif severity == "WARN"
25 | "[#{date_format}] #{severity} (#{progname}): #{msg}\n".orange
26 | else
27 | "[#{date_format}] #{severity} (#{progname}): #{msg}\n".red
28 | end
29 | end
30 |
31 | DB.loggers << logger if logger
32 |
33 | require './roda_graphql'
34 | run RodaGraphql
35 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/db/migrate/1_user.rb:
--------------------------------------------------------------------------------
1 | Sequel.migration do
2 | up do
3 | create_table(:users) do
4 | primary_key :id
5 | String :first_name, :null=>false
6 | String :last_name, :null=>false
7 | String :email, :null=>false
8 | String :username, :null=>false
9 | end
10 | end
11 |
12 | down do
13 | drop_table(:users)
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/db/migrate/2_post.rb:
--------------------------------------------------------------------------------
1 | Sequel.migration do
2 | up do
3 | create_table(:posts) do
4 | primary_key :id
5 | String :title, :null=>false
6 | String :body, :null=>false
7 | foreign_key :user_id, :users
8 | end
9 | end
10 |
11 | down do
12 | drop_table(:posts)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/db/migrate/3_comment.rb:
--------------------------------------------------------------------------------
1 | Sequel.migration do
2 | up do
3 | create_table(:comments) do
4 | primary_key :id
5 | String :body, :null=>false
6 | foreign_key :user_id, :users
7 | foreign_key :post_id, :posts
8 | end
9 | end
10 |
11 | down do
12 | drop_table(:comments)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/db/seeds/20150928000000_seed.rb:
--------------------------------------------------------------------------------
1 | Sequel.seed do # Applies only to "development" and "test" environments
2 | def run
3 | user = DB[:users]
4 | post = DB[:posts]
5 | comment = DB[:comments]
6 |
7 | [
8 | ['John', 'Doe', 'john@doe.com', 'johndoe'],
9 | ['Maggie', 'Turner', 'maggie@turner.com', 'maggie']
10 | ].each do |first_name, last_name, email, username|
11 | user.insert first_name: first_name, last_name: last_name, email: email, username: username
12 | end
13 |
14 | [
15 | ['First post title', 'First post body', 1],
16 | ['Second Post title', 'Second post body', 2]
17 | ].each do |title, body, user_id|
18 | post.insert title: title, body: body, user_id: user_id
19 | end
20 |
21 | [
22 | ['First post comment body', 1, 1],
23 | ['Second Post comment body', 2, 2]
24 | ].each do |body, post_id, user_id|
25 | comment.insert body: body, post_id: post_id, user_id: user_id
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/middlewares/pass_auth_token.rb:
--------------------------------------------------------------------------------
1 | # Inject authorization token for root route
2 | # Because we don't have it
3 | # For real app you would use generally some kind of authentication
4 |
5 | class PassAuthToken
6 | def initialize(app)
7 | @app = app
8 | end
9 |
10 | def call(env)
11 | data = {user_id: 1} # Anything you want to encode
12 | token = Rack::JWT::Token.encode(data, ENV['RACK_COOKIE_SECRET'], 'HS256')
13 | if env['REQUEST_PATH'] == '/'
14 | env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
15 | end
16 | @app.call(env)
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/roda_graphql.rb:
--------------------------------------------------------------------------------
1 | require './api/schema'
2 |
3 | Dotenv.load
4 |
5 | class RodaGraphql < Roda
6 | use Rack::Session::Cookie, key: ENV['RACK_COOKIE_KEY'], secret: ENV['RACK_COOKIE_SECRET']
7 | use Rack::Protection
8 | use Rack::Protection::RemoteReferrer
9 | use PassAuthToken
10 | use Rack::JWT::Auth, {secret: ENV['RACK_COOKIE_SECRET'], exclude: %w(/assets), options: { algorithm: 'HS256' }}
11 |
12 | plugin :environments
13 | self.environment = ENV['ENVIRONMENT']
14 |
15 | plugin :flash
16 | plugin :json
17 | plugin :json_parser
18 | plugin :render, engine: 'erb'
19 | plugin :view_options
20 | plugin :assets
21 | plugin :multi_route
22 |
23 | require './assets/assets'
24 |
25 | require './api/routes/main.rb'
26 | Dir['./routes/*.rb'].each{|f| require f}
27 | end
28 |
--------------------------------------------------------------------------------
/ruby/roda_graphql/views/layout.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Roda Graphql
13 |
14 | <%= assets(:css) %>
15 | <%= assets(:js) %>
16 |
17 |
21 |
22 |
23 | <%= yield %>
24 |
25 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle
2 | vendor/bundle
3 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org/'
2 |
3 | # App Stack
4 | gem 'sinatra', '>= 1.4'
5 |
6 | # Database Stack
7 | gem 'sequel'
8 | gem 'sequel-seed'
9 | gem 'pg'
10 | gem 'puma'
11 | gem 'colorize'
12 | gem 'rack-protection'
13 |
14 | # Graphql
15 | gem 'graphql'
16 | gem 'json'
17 |
18 | # Token
19 | gem 'rack-jwt'
20 |
21 | group :development do
22 | gem 'rake', '~> 10.0'
23 | gem 'minitest', '~> 5.2'
24 | gem 'rack-test', '~> 0.6'
25 | end
26 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | colorize (0.8.1)
5 | graphql (0.18.11)
6 | json (2.0.2)
7 | jwt (1.5.5)
8 | minitest (5.9.0)
9 | pg (0.18.4)
10 | puma (3.6.0)
11 | rack (1.6.4)
12 | rack-jwt (0.3.0)
13 | jwt (~> 1.5.2)
14 | rack (>= 1.6.0)
15 | rack-protection (1.5.3)
16 | rack
17 | rack-test (0.6.3)
18 | rack (>= 1.0)
19 | rake (10.5.0)
20 | sequel (4.38.0)
21 | sequel-seed (1.0.0)
22 | sequel (>= 4.0)
23 | sinatra (1.4.7)
24 | rack (~> 1.5)
25 | rack-protection (~> 1.4)
26 | tilt (>= 1.3, < 3)
27 | tilt (2.0.5)
28 |
29 | PLATFORMS
30 | ruby
31 |
32 | DEPENDENCIES
33 | colorize
34 | graphql
35 | json
36 | minitest (~> 5.2)
37 | pg
38 | puma
39 | rack-jwt
40 | rack-protection
41 | rack-test (~> 0.6)
42 | rake (~> 10.0)
43 | sequel
44 | sequel-seed
45 | sinatra (>= 1.4)
46 |
47 | BUNDLED WITH
48 | 1.12.5
49 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/README.md:
--------------------------------------------------------------------------------
1 | # Sinatra Graphql Server
2 |
3 | ### Setup and Running locally
4 |
5 | ```bash
6 | git clone repo
7 | cd to folder
8 | bundle install
9 | # make sure postgres is installed
10 | createdb sinatra_graphql_development
11 | bundle exec rake db:migrate
12 | bundle exec rake db:seed
13 | # run the server
14 | bundle exec rackup -p 3000
15 | # Visit http://localhost:3000
16 | ```
17 |
18 | [Visit browser](http://localhost:3000)
19 |
20 | # Features
21 | * Graphql API
22 | * CSRF and SESSION
23 | * TOKEN AUTH
24 |
25 | ### Supported API Queries
26 | ```
27 | {
28 | all_posts {
29 | id,
30 | title,
31 | body,
32 | user {
33 | id,
34 | first_name
35 | }
36 | comments {
37 | id,
38 | body
39 | user {
40 | id,
41 | first_name
42 | }
43 | }
44 |
45 | }
46 | }
47 | ```
48 |
49 | ```
50 | {
51 | post(id: 2) {
52 | id,
53 | title,
54 | body,
55 | user {
56 | id,
57 | first_name
58 | }
59 | comments {
60 | id,
61 | body
62 | user {
63 | id,
64 | first_name
65 | }
66 | }
67 |
68 | }
69 | }
70 | ```
71 |
72 | ### DB
73 | * Postgresql (with ruby Sequel ORM)
74 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/Rakefile:
--------------------------------------------------------------------------------
1 | %w{ bundler find rake/testtask}.each { |lib| require lib }
2 | require 'sequel'
3 |
4 | task :default => :spec
5 |
6 | Rake::TestTask.new(:spec) do |t|
7 | t.test_files = FileList['spec/*_spec.rb']
8 | end
9 |
10 | namespace :db do
11 | task :environment do
12 | puts 'task environment'
13 | end
14 | desc "Run all migrations in db/migrate"
15 | task :migrate => :connect do
16 | Sequel.extension(:migration)
17 | Sequel::Migrator.apply(DB, "db/migrate")
18 | end
19 |
20 | task :seed => :connect do
21 | Sequel.extension(:seed)
22 | Sequel::Seeder.apply(DB, "db/seeds")
23 | end
24 |
25 | task :connect => :environment do
26 | require "./config/initializers/database"
27 | Dir.glob('./lib/{models}/*.rb').each { |file| require file }
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/config.ru:
--------------------------------------------------------------------------------
1 | # Load path and gems/bundler
2 | $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
3 | require 'tilt/erb'
4 | require 'bundler'
5 | require 'logger'
6 | require 'colorize'
7 | Bundler.require
8 | # Local config
9 | require "find"
10 |
11 | %w{config/initializers lib middlewares}.each do |load_path|
12 | Find.find(load_path) { |f|
13 | require f unless f.match(/\/\..+$/) || File.directory?(f)
14 | }
15 | end
16 |
17 | logger = Logger.new(STDOUT)
18 |
19 | logger.level = Logger::DEBUG
20 | logger.formatter = proc do |severity, datetime, progname, msg|
21 | date_format = datetime.strftime("%Y-%m-%d %H:%M:%S")
22 | if severity == "INFO"
23 | "[#{date_format}] #{severity} (#{progname}): #{msg}\n".blue
24 | elsif severity == "WARN"
25 | "[#{date_format}] #{severity} (#{progname}): #{msg}\n".orange
26 | else
27 | "[#{date_format}] #{severity} (#{progname}): #{msg}\n".red
28 | end
29 | end
30 |
31 | DB << "SET CLIENT_ENCODING TO 'UTF8';"
32 | DB.loggers << logger if logger
33 |
34 | # Load app
35 | require "sinatra_graphql"
36 | run SinatraGraphql
37 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/config/db.yml:
--------------------------------------------------------------------------------
1 | # Sequel Database Configuration
2 |
3 | development: "postgres://gaurav@localhost/sinatra_graphql_development"
4 | test: "postgres://gaurav@localhost/sinatra_graphql_test"
5 | production: "postgres://gaurav@localhost/sinatra_graphql_production"
6 |
7 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/config/initializers/database.rb:
--------------------------------------------------------------------------------
1 | require "yaml"
2 | settings = YAML::load_file("config/db.yml")
3 | # Sequel Configuration
4 | DB = Sequel.connect(settings[ENV['RACK_ENV']])
5 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/db/migrate/1_user.rb:
--------------------------------------------------------------------------------
1 | Sequel.migration do
2 | up do
3 | create_table(:users) do
4 | primary_key :id
5 | String :first_name, :null=>false
6 | String :last_name, :null=>false
7 | String :email, :null=>false
8 | String :username, :null=>false
9 | end
10 | end
11 |
12 | down do
13 | drop_table(:users)
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/db/migrate/2_post.rb:
--------------------------------------------------------------------------------
1 | Sequel.migration do
2 | up do
3 | create_table(:posts) do
4 | primary_key :id
5 | String :title, :null=>false
6 | String :body, :null=>false
7 | foreign_key :user_id, :users
8 | end
9 | end
10 |
11 | down do
12 | drop_table(:posts)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/db/migrate/3_comment.rb:
--------------------------------------------------------------------------------
1 | Sequel.migration do
2 | up do
3 | create_table(:comments) do
4 | primary_key :id
5 | String :body, :null=>false
6 | foreign_key :user_id, :users
7 | foreign_key :post_id, :posts
8 | end
9 | end
10 |
11 | down do
12 | drop_table(:comments)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/db/seeds/20150928000000_seed.rb:
--------------------------------------------------------------------------------
1 | Sequel.seed do # Applies only to "development" and "test" environments
2 | def run
3 | [
4 | ['John', 'Doe', 'john@doe.com', 'johndoe'],
5 | ['Maggie', 'Turner', 'maggie@turner.com', 'maggie']
6 | ].each do |first_name, last_name, email, username|
7 | User.create first_name: first_name, last_name: last_name, email: email, username: username
8 | end
9 |
10 | [
11 | ['First post title', 'First post body', 1],
12 | ['Second Post title', 'Second post body', 2]
13 | ].each do |title, body, user_id|
14 | Post.create title: title, body: body, user_id: user_id
15 | end
16 |
17 | [
18 | ['First post comment body', 1, 1],
19 | ['Second Post comment body', 2, 2]
20 | ].each do |body, post_id, user_id|
21 | Comment.create body: body, post_id: post_id, user_id: user_id
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/sinatra_graphql/lib/.gitkeep
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/api/node_identification.rb:
--------------------------------------------------------------------------------
1 | NodeIdentification = GraphQL::Relay::GlobalNodeIdentification.define do
2 | object_from_id -> (id, ctx) do
3 | type_name, id = NodeIdentification.from_global_id(id)
4 | Object.const_get(type_name).find(id)
5 | end
6 |
7 | type_from_object -> (object) do
8 | Schema.types[type_name(object)]
9 | end
10 | end
11 |
12 | def type_name(object)
13 | object.class.name
14 | end
15 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/api/schema.rb:
--------------------------------------------------------------------------------
1 | require_relative 'types/post_type'
2 | require_relative 'node_identification'
3 |
4 | QueryType = GraphQL::ObjectType.define do
5 | name "Query"
6 | description "The query root of this schema"
7 | field :node, field: NodeIdentification.field
8 |
9 | field :post do
10 | type PostType
11 | argument :id, !types.ID
12 | resolve -> (obj, args, ctx) { Post.find(id: args["id"]) }
13 | end
14 |
15 | field :all_posts do
16 | type types[!PostType]
17 | resolve -> (obj, args, ctx) { Post.all }
18 | end
19 | end
20 |
21 | Schema = GraphQL::Schema.new(
22 | query: QueryType
23 | )
24 |
25 | Schema.node_identification = NodeIdentification
26 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/api/types/comment_type.rb:
--------------------------------------------------------------------------------
1 | CommentType = GraphQL::ObjectType.define do
2 | name "Comment"
3 | description "A comment"
4 | interfaces [NodeIdentification.interface]
5 | global_id_field :id
6 |
7 | field :id, !types.ID
8 | field :body, !types.String
9 | field :user, -> { UserType }
10 | field :post, -> { PostType }
11 | end
12 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/api/types/post_type.rb:
--------------------------------------------------------------------------------
1 | PostType = GraphQL::ObjectType.define do
2 | name "Post"
3 | description "A post"
4 | interfaces [NodeIdentification.interface]
5 | global_id_field :id
6 |
7 | field :title, !types.String
8 | field :body, !types.String
9 | field :user, -> { UserType }
10 | field :comments, -> { types[!CommentType] }
11 | end
12 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/api/types/user_type.rb:
--------------------------------------------------------------------------------
1 | UserType = GraphQL::ObjectType.define do
2 | name "User"
3 | description "A user"
4 | interfaces [NodeIdentification.interface]
5 | global_id_field :id
6 |
7 | field :first_name, !types.String
8 | field :last_name, !types.String
9 | field :username, !types.String
10 | field :email, !types.String
11 | field :posts, -> { types[!PostType] }
12 | field :comments, -> { types[!CommentType] }
13 | end
14 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/models/comment.rb:
--------------------------------------------------------------------------------
1 | class Comment < Sequel::Model
2 | many_to_one :post
3 | many_to_one :user
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/models/post.rb:
--------------------------------------------------------------------------------
1 | class Post < Sequel::Model
2 | one_to_many :comments
3 | many_to_one :user
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/lib/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < Sequel::Model
2 | one_to_many :comments
3 | one_to_many :posts
4 | end
5 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/logs/common.log:
--------------------------------------------------------------------------------
1 | # Logfile created on 2016-06-01 10:43:07 +0100 by logger.rb/54362
2 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/logs/output.log:
--------------------------------------------------------------------------------
1 | [2016-06-01 10:43:08] INFO WEBrick 1.3.1
2 | [2016-06-01 10:43:08] INFO ruby 2.3.1 (2016-04-26) [x86_64-darwin15]
3 | [2016-06-01 10:43:08] INFO WEBrick::HTTPServer#start: pid=23992 port=3000
4 | [2016-06-01 10:44:07] INFO going to shutdown ...
5 | [2016-06-01 10:44:07] INFO WEBrick::HTTPServer#start done.
6 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/middlewares/pass_auth_token.rb:
--------------------------------------------------------------------------------
1 | # Inject authorization token for root route
2 | # Because we don't have it
3 | # For real app you would use generally some kind of authentication
4 |
5 | class PassAuthToken
6 | def initialize(app)
7 | @app = app
8 | end
9 |
10 | def call(env)
11 | data = {user_id: 1} # Anything you want to encode
12 | token = Rack::JWT::Token.encode(data, 'super_secret_key', 'HS256')
13 | if env['REQUEST_PATH'] == '/'
14 | env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
15 | end
16 | @app.call(env)
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/sinatra_graphql/public/favicon.ico
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/sinatra_graphql/public/images/.gitkeep
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/images/hazel_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/sinatra_graphql/public/images/hazel_icon.png
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/images/hazel_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/sinatra_graphql/public/images/hazel_small.png
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/javascripts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/ruby/sinatra_graphql/public/javascripts/.gitkeep
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/javascripts/application.js:
--------------------------------------------------------------------------------
1 | //= require ./react-15.0.1
2 | //= require ./react-dom-15.0.1
3 | //= require ./fetch-0.10.1
4 | //= require ./graphiql-0.7.0
5 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/public/stylesheets/application.css:
--------------------------------------------------------------------------------
1 |
2 | @import "graphiql-0.7.0.css";
3 | @import "main.css";
4 |
5 | html, body {
6 | height: 100%;
7 | margin: 0;
8 | overflow: hidden;
9 | width: 100%;
10 | }
11 |
--------------------------------------------------------------------------------
/ruby/sinatra_graphql/sinatra_graphql.rb:
--------------------------------------------------------------------------------
1 | require 'rack/protection'
2 |
3 | class SinatraGraphql < Sinatra::Base
4 | set public_folder: 'public', static: true
5 | use Rack::Session::Cookie, secret: 'super_secret_key'
6 | use Rack::Protection
7 | use Rack::Protection::RemoteReferrer
8 | use PassAuthToken
9 | use Rack::JWT::Auth, {secret: 'super_secret_key', exclude: %w(/javascripts /stylesheets), options: { algorithm: 'HS256' }}
10 |
11 | get '/' do
12 | data = {user_id: 1}
13 | token = Rack::JWT::Token.encode(data, 'super_secret_key', 'HS256')
14 | puts token
15 | erb :graphiql, locals: {token: token}
16 | end
17 |
18 | post '/graphql' do
19 | params = JSON.parse(request.body.read)
20 | result = Schema.execute(
21 | params['query'],
22 | variables: params['variables']
23 | )
24 | content_type :json
25 | result.to_json
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/scala/README.md:
--------------------------------------------------------------------------------
1 | # Scala based web frameworks
2 |
3 | A set of GraphQL server implementation on popular Scala web frameworks.
4 |
--------------------------------------------------------------------------------
/scala/play_grapgql/.gitignore:
--------------------------------------------------------------------------------
1 | logs
2 | target
3 | /.idea
4 | /.idea_modules
5 | /.classpath
6 | /.project
7 | /.settings
8 | /RUNNING_PID
9 |
--------------------------------------------------------------------------------
/scala/play_grapgql/LICENSE:
--------------------------------------------------------------------------------
1 | This software is licensed under the Apache 2 license, quoted below.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with
4 | the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
5 |
6 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
7 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
8 | language governing permissions and limitations under the License.
--------------------------------------------------------------------------------
/scala/play_grapgql/README:
--------------------------------------------------------------------------------
1 | This is your new Play application
2 | =================================
3 |
4 | This file will be packaged with your application when using `activator dist`.
5 |
6 | There are several demonstration files available in this template.
7 |
8 | Controllers
9 | ===========
10 |
11 | - HomeController.scala:
12 |
13 | Shows how to handle simple HTTP requests.
14 |
15 | - AsyncController.scala:
16 |
17 | Shows how to do asynchronous programming when handling a request.
18 |
19 | - CountController.scala:
20 |
21 | Shows how to inject a component into a controller and use the component when
22 | handling requests.
23 |
24 | Components
25 | ==========
26 |
27 | - Module.scala:
28 |
29 | Shows how to use Guice to bind all the components needed by your application.
30 |
31 | - Counter.scala:
32 |
33 | An example of a component that contains state, in this case a simple counter.
34 |
35 | - ApplicationTimer.scala:
36 |
37 | An example of a component that starts when the application starts and stops
38 | when the application stops.
39 |
40 | Filters
41 | =======
42 |
43 | - Filters.scala:
44 |
45 | Creates the list of HTTP filters used by your application.
46 |
47 | - ExampleFilter.scala
48 |
49 | A simple filter that adds a header to every response.
--------------------------------------------------------------------------------
/scala/play_grapgql/app/Filters.scala:
--------------------------------------------------------------------------------
1 | import javax.inject._
2 | import play.api._
3 | import play.api.http.HttpFilters
4 | import play.api.mvc._
5 |
6 | import filters.ExampleFilter
7 |
8 | /**
9 | * This class configures filters that run on every request. This
10 | * class is queried by Play to get a list of filters.
11 | *
12 | * Play will automatically use filters from any class called
13 | * `Filters` that is placed the root package. You can load filters
14 | * from a different class by adding a `play.http.filters` setting to
15 | * the `application.conf` configuration file.
16 | *
17 | * @param env Basic environment settings for the current application.
18 | * @param exampleFilter A demonstration filter that adds a header to
19 | * each response.
20 | */
21 | @Singleton
22 | class Filters @Inject() (
23 | env: Environment,
24 | exampleFilter: ExampleFilter) extends HttpFilters {
25 |
26 | override val filters = {
27 | // Use the example filter if we're running development mode. If
28 | // we're running in production or test mode then don't use any
29 | // filters at all.
30 | if (env.mode == Mode.Dev) Seq(exampleFilter) else Seq.empty
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/Module.scala:
--------------------------------------------------------------------------------
1 | import com.google.inject.AbstractModule
2 | import java.time.Clock
3 |
4 | import services.{ApplicationTimer, AtomicCounter, Counter}
5 |
6 | /**
7 | * This class is a Guice module that tells Guice how to bind several
8 | * different types. This Guice module is created when the Play
9 | * application starts.
10 |
11 | * Play will automatically use any class called `Module` that is in
12 | * the root package. You can create modules in other locations by
13 | * adding `play.modules.enabled` settings to the `application.conf`
14 | * configuration file.
15 | */
16 | class Module extends AbstractModule {
17 |
18 | override def configure() = {
19 | // Use the system clock as the default implementation of Clock
20 | bind(classOf[Clock]).toInstance(Clock.systemDefaultZone)
21 | // Ask Guice to create an instance of ApplicationTimer when the
22 | // application starts.
23 | bind(classOf[ApplicationTimer]).asEagerSingleton()
24 | // Set AtomicCounter as the implementation for Counter.
25 | bind(classOf[Counter]).to(classOf[AtomicCounter])
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/controllers/CountController.scala:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import javax.inject._
4 | import play.api._
5 | import play.api.mvc._
6 |
7 | import services.Counter
8 |
9 | /**
10 | * This controller demonstrates how to use dependency injection to
11 | * bind a component into a controller class. The class creates an
12 | * `Action` that shows an incrementing count to users. The [[Counter]]
13 | * object is injected by the Guice dependency injection system.
14 | */
15 | @Singleton
16 | class CountController @Inject() (counter: Counter) extends Controller {
17 |
18 | /**
19 | * Create an action that responds with the [[Counter]]'s current
20 | * count. The result is plain text. This `Action` is mapped to
21 | * `GET /count` requests by an entry in the `routes` config file.
22 | */
23 | def count = Action { Ok(counter.nextCount().toString) }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/controllers/HomeController.scala:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import javax.inject._
4 | import play.api._
5 | import play.api.mvc._
6 |
7 | /**
8 | * This controller creates an `Action` to handle HTTP requests to the
9 | * application's home page.
10 | */
11 | @Singleton
12 | class HomeController @Inject() extends Controller {
13 |
14 | /**
15 | * Create an Action to render an HTML page with a welcome message.
16 | * The configuration in the `routes` file means that this method
17 | * will be called when the application receives a `GET` request with
18 | * a path of `/`.
19 | */
20 | def index = Action {
21 | Ok(views.html.index("Your new application is ready."))
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/filters/ExampleFilter.scala:
--------------------------------------------------------------------------------
1 | package filters
2 |
3 | import akka.stream.Materializer
4 | import javax.inject._
5 | import play.api.mvc._
6 | import scala.concurrent.{ExecutionContext, Future}
7 |
8 | /**
9 | * This is a simple filter that adds a header to all requests. It's
10 | * added to the application's list of filters by the
11 | * [[ExampleFilters]] class.
12 | *
13 | * @param mat This object is needed to handle streaming of requests
14 | * and responses.
15 | * @param exec This class is needed to execute code asynchronously.
16 | * It is used below by the `map` method.
17 | */
18 | @Singleton
19 | class ExampleFilter @Inject()(
20 | implicit override val mat: Materializer,
21 | exec: ExecutionContext) extends Filter {
22 |
23 | override def apply(nextFilter: RequestHeader => Future[Result])
24 | (requestHeader: RequestHeader): Future[Result] = {
25 | // Run the next filter in the chain. This will call other filters
26 | // and eventually call the action. Take the result and modify it
27 | // by adding a new header.
28 | nextFilter(requestHeader).map { result =>
29 | result.withHeaders("X-ExampleFilter" -> "foo")
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/services/Counter.scala:
--------------------------------------------------------------------------------
1 | package services
2 |
3 | import java.util.concurrent.atomic.AtomicInteger
4 | import javax.inject._
5 |
6 | /**
7 | * This trait demonstrates how to create a component that is injected
8 | * into a controller. The trait represents a counter that returns a
9 | * incremented number each time it is called.
10 | */
11 | trait Counter {
12 | def nextCount(): Int
13 | }
14 |
15 | /**
16 | * This class is a concrete implementation of the [[Counter]] trait.
17 | * It is configured for Guice dependency injection in the [[Module]]
18 | * class.
19 | *
20 | * This class has a `Singleton` annotation because we need to make
21 | * sure we only use one counter per application. Without this
22 | * annotation we would get a new instance every time a [[Counter]] is
23 | * injected.
24 | */
25 | @Singleton
26 | class AtomicCounter extends Counter {
27 | private val atomicCounter = new AtomicInteger()
28 | override def nextCount(): Int = atomicCounter.getAndIncrement()
29 | }
30 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/views/index.scala.html:
--------------------------------------------------------------------------------
1 | @*
2 | * This template takes a single argument, a String containing a
3 | * message to display.
4 | *@
5 | @(message: String)
6 |
7 | @*
8 | * Call the `main` template with two arguments. The first
9 | * argument is a `String` with the title of the page, the second
10 | * argument is an `Html` object containing the body of the page.
11 | *@
12 | @main("Welcome to Play") {
13 |
14 | @*
15 | * Get an `Html` object by calling the built-in Play welcome
16 | * template and passing a `String` message.
17 | *@
18 | @play20.welcome(message, style = "Scala")
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/scala/play_grapgql/app/views/main.scala.html:
--------------------------------------------------------------------------------
1 | @*
2 | * This template is called from the `index` template. This template
3 | * handles the rendering of the page header and body tags. It takes
4 | * two arguments, a `String` for the title of the page and an `Html`
5 | * object to insert into the body of the page.
6 | *@
7 | @(title: String)(content: Html)
8 |
9 |
10 |
11 |
12 | @* Here's where we render the page title `String`. *@
13 | @title
14 |
15 |
16 |
17 |
18 |
19 | @* And here's where we render the `Html` object containing
20 | * the page content. *@
21 | @content
22 |
23 |
24 |
--------------------------------------------------------------------------------
/scala/play_grapgql/build.sbt:
--------------------------------------------------------------------------------
1 | name := """play_grapgql"""
2 |
3 | version := "1.0-SNAPSHOT"
4 |
5 | lazy val root = (project in file(".")).enablePlugins(PlayScala)
6 |
7 | scalaVersion := "2.11.7"
8 |
9 | libraryDependencies ++= Seq(
10 | jdbc,
11 | cache,
12 | ws,
13 | "org.sangria-graphql" %% "sangria" % "0.6.3",
14 | "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test
15 | )
16 |
17 | resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
18 |
--------------------------------------------------------------------------------
/scala/play_grapgql/conf/routes:
--------------------------------------------------------------------------------
1 | # Routes
2 | # This file defines all application routes (Higher priority routes first)
3 | # ~~~~
4 |
5 | # An example controller showing a sample home page
6 | GET / controllers.HomeController.index
7 | # An example controller showing how to use dependency injection
8 | GET /count controllers.CountController.count
9 | # An example controller showing how to write asynchronous code
10 | GET /message controllers.AsyncController.message
11 |
12 | # Map static resources from the /public folder to the /assets URL path
13 | GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
14 |
--------------------------------------------------------------------------------
/scala/play_grapgql/libexec/activator-launch-1.3.10.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/scala/play_grapgql/libexec/activator-launch-1.3.10.jar
--------------------------------------------------------------------------------
/scala/play_grapgql/project/build.properties:
--------------------------------------------------------------------------------
1 | #Activator-generated Properties
2 | #Mon May 23 04:30:52 BST 2016
3 | template.uuid=15c371e1-78e0-429a-84ff-11b1d09dd4a2
4 | sbt.version=0.13.11
5 |
--------------------------------------------------------------------------------
/scala/play_grapgql/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | // The Play plugin
2 | addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.3")
3 |
4 | // web plugins
5 |
6 | addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")
7 |
8 | addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0")
9 |
10 | addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.3")
11 |
12 | addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.7")
13 |
14 | addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.0")
15 |
16 | addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0")
17 |
18 | addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.2")
19 |
--------------------------------------------------------------------------------
/scala/play_grapgql/public/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/scala/play_grapgql/public/images/favicon.png
--------------------------------------------------------------------------------
/scala/play_grapgql/public/javascripts/hello.js:
--------------------------------------------------------------------------------
1 | if (window.console) {
2 | console.log("Welcome to your Play application's JavaScript!");
3 | }
4 |
--------------------------------------------------------------------------------
/scala/play_grapgql/public/stylesheets/main.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravtiwari/graphql-server-examples/8f993d4507c5738ab5d1d81c3d43b74f748c8d05/scala/play_grapgql/public/stylesheets/main.css
--------------------------------------------------------------------------------
/scala/play_grapgql/test/ApplicationSpec.scala:
--------------------------------------------------------------------------------
1 | import org.scalatestplus.play._
2 | import play.api.test._
3 | import play.api.test.Helpers._
4 |
5 | /**
6 | * Add your spec here.
7 | * You can mock out a whole application including requests, plugins etc.
8 | * For more information, consult the wiki.
9 | */
10 | class ApplicationSpec extends PlaySpec with OneAppPerTest {
11 |
12 | "Routes" should {
13 |
14 | "send 404 on a bad request" in {
15 | route(app, FakeRequest(GET, "/boum")).map(status(_)) mustBe Some(NOT_FOUND)
16 | }
17 |
18 | }
19 |
20 | "HomeController" should {
21 |
22 | "render the index page" in {
23 | val home = route(app, FakeRequest(GET, "/")).get
24 |
25 | status(home) mustBe OK
26 | contentType(home) mustBe Some("text/html")
27 | contentAsString(home) must include ("Your new application is ready.")
28 | }
29 |
30 | }
31 |
32 | "CountController" should {
33 |
34 | "return an increasing count" in {
35 | contentAsString(route(app, FakeRequest(GET, "/count")).get) mustBe "0"
36 | contentAsString(route(app, FakeRequest(GET, "/count")).get) mustBe "1"
37 | contentAsString(route(app, FakeRequest(GET, "/count")).get) mustBe "2"
38 | }
39 |
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/scala/play_grapgql/test/IntegrationSpec.scala:
--------------------------------------------------------------------------------
1 | import org.scalatestplus.play._
2 | import play.api.test._
3 | import play.api.test.Helpers._
4 |
5 | /**
6 | * add your integration spec here.
7 | * An integration test will fire up a whole play application in a real (or headless) browser
8 | */
9 | class IntegrationSpec extends PlaySpec with OneServerPerTest with OneBrowserPerTest with HtmlUnitFactory {
10 |
11 | "Application" should {
12 |
13 | "work from within a browser" in {
14 |
15 | go to ("http://localhost:" + port)
16 |
17 | pageSource must include ("Your new application is ready.")
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------