All Projects → tb → northwind-graphql-ruby

tb / northwind-graphql-ruby

Licence: other
Northwind graphql-ruby

Programming Languages

ruby
36898 projects - #4 most used programming language
javascript
184084 projects - #8 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to northwind-graphql-ruby

delimeal
The Android template app for restaurant or booking item.
Stars: ✭ 26 (+4%)
Mutual labels:  demo-app
laravel-realworld-example-app
Exemplary RealWorld backend API built with Laravel PHP framework.
Stars: ✭ 34 (+36%)
Mutual labels:  demo-app
my-first-realm-app
ToDo demo app using Realm and Realm Object Server to synchronize tasks.
Stars: ✭ 38 (+52%)
Mutual labels:  demo-app
purescript-pop
😃 A functional reactive programming (FRP) demo created with PureScript events and behaviors.
Stars: ✭ 33 (+32%)
Mutual labels:  demo-app
get-involved
Get Involved with Docker
Stars: ✭ 20 (-20%)
Mutual labels:  workshops
RxSwift-Workshops
EL Passion - RxSwift Workshops
Stars: ✭ 41 (+64%)
Mutual labels:  workshops
Flashcards-Demo
This is a source code for a demo app.
Stars: ✭ 18 (-28%)
Mutual labels:  demo-app
ARKit-SceneKit-Paint-Tiltbrush-Demo
Demo paint app with ARKit and SceneKit
Stars: ✭ 33 (+32%)
Mutual labels:  demo-app
food-ordering-demo
Demo application focusing on the Food Ordering domain - Used in our video series
Stars: ✭ 28 (+12%)
Mutual labels:  demo-app
transit
Massively real-time city transit streaming application
Stars: ✭ 20 (-20%)
Mutual labels:  demo-app
demo-api
www.yiiframework.com/
Stars: ✭ 23 (-8%)
Mutual labels:  demo-app
containers-101-workshop
Docker Linux Containers 101 Workshop
Stars: ✭ 18 (-28%)
Mutual labels:  workshops
traffic
Massively real-time traffic streaming application
Stars: ✭ 25 (+0%)
Mutual labels:  demo-app
react-native-css-modules-with-typescript-example
A simple example app that shows how you can use CSS modules + Typescript with React Native and React (for browser)
Stars: ✭ 17 (-32%)
Mutual labels:  demo-app
react-sample-projects
The goal of this project is to provide a set of simple samples, providing and step by step guide to start working with React.
Stars: ✭ 30 (+20%)
Mutual labels:  demo-app
circularProgressBar
This repo contains a demo app for circularProgressBar.swift
Stars: ✭ 17 (-32%)
Mutual labels:  demo-app
real-world-bazel
The real world Angular example app moved to Bazel
Stars: ✭ 91 (+264%)
Mutual labels:  demo-app
react-native-css-modules-with-media-queries-example
An example app to show how CSS Media Queries work in React Native.
Stars: ✭ 18 (-28%)
Mutual labels:  demo-app
gofun-android
Motivates you to go home 🏡 and live your life
Stars: ✭ 22 (-12%)
Mutual labels:  demo-app
android-constraintlayout-demo
Demo usage of various ConstraintLayout features
Stars: ✭ 49 (+96%)
Mutual labels:  demo-app

northwind-graphql-ruby

by GraphQL Developers @ Selleo

Build Status

Demo

GitHub Logo

Initial project setup

gem install rails
rails new northwind-graphql-ruby --api --database=postgresql
echo northwind-graphql-ruby > northwind-graphql-ruby/.ruby-gemset
echo 2.4.2 > northwind-graphql-ruby/.ruby-version
cd northwind-graphql-ruby
gem install bundler

Setup data

rake db:setup

See Entity-Relationship Diagrams PDF

Setup GraphQL

Add to Gemfile

gem 'graphql'
gem 'batch-loader'

group :development do
  # ...
  # graphiql in development https://github.com/rmosolgo/graphiql-rails/issues/13#issuecomment-256256255
  gem 'sass-rails'
  gem 'uglifier'
  gem 'coffee-rails'
  gem 'graphiql-rails'
end

Then run

bundle
rails generate graphql:install

Add the engine to routes.rb

Rails.application.routes.draw do
  post "/graphql", to: "graphql#execute"
  if Rails.env.development?
    mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"
  end
end

And start server

rails s
open http://localhost:3000/graphiql

Query GraphQL API

query { testField }

Read Introduction to GraphQL

Types

GraphQL queries begin from root types: query, mutation, and subscription (experimental).

Types describe objects and values in a system.

To query and mutate models we will define two types for each model

Types::SupplierType = GraphQL::ObjectType.define do
  name "Supplier"

  field :id, !types.ID
  field :name, types.String
  field :webpage, types.String
  field :notes, types.String
  field :errors, Types::JSONType
end

Types::SupplierInputType = GraphQL::InputObjectType.define do
  name "SupplierInput"

  argument :id, types.ID
  argument :name, types.String
  argument :webpage, types.String
  argument :notes, types.String
end

and some custom types with GraphQL::ScalarTypes like

Types::DateType = GraphQL::ScalarType.define do
  name "Date"

  coerce_input ->(value, ctx) { Date.iso8601(value) }
  coerce_result ->(value, ctx) { value.iso8601 }
end

Queries

To keep schema definition clean use GraphQL::Function

Types::QueryType = GraphQL::ObjectType.define do
  name "Query"

  field :supplier, function: Functions::FindById.new(Supplier)
  field :allSuppliers, function: Functions::FindAll.new(Supplier) do
    argument :filter, Types::SupplierFilterType
  end
end

Above defines queries

fragment supplierFields on Supplier {
  id
  name
}

{
  supplier(id: 1) {
    ...supplierFields
  }
  allSuppliers(offset: 1) {
    ...supplierFields
  }
}

Mutations

For mutations also use GraphQL::Function

Types::MutationType = GraphQL::ObjectType.define do
  name "Mutation"

  field :createSupplier, function: Functions::Create.new(Supplier) do
    argument :supplier, !Types::SupplierInputType
  end
  field :updateSupplier, function: Functions::Update.new(Supplier) do
    argument :supplier, !Types::SupplierInputType
  end
  field :deleteSupplier, function: Functions::Delete.new(Supplier)
end

Try mutations (run one mutation at a time)

fragment supplierFields on Supplier {
  id
  name
}

mutation {
  createSupplier(supplier: {name: "ACME"}) {
    ...supplierFields
    errors
  }
}

mutation {
  updateSupplier(supplier: {id: 11, name: "NewCo"}) {
    ...supplierFields
    errors
  }
}

mutation {
  deleteSupplier(id: 11) {
    ...supplierFields
  }
}

We are using Types::JSONType to get validation errors, read more on Error Handling

Relations

For one-to-one relations use Functions::HasOne that is wrapper around exAspArk/batch-loader, "Powerful tool to avoid N+1 DB or HTTP queries".

For one-to-many relations you can reuse Functions::FindAll.

Types::SupplierType = GraphQL::ObjectType.define do
  name "Supplier"
  #...

  field :contact, function: Functions::HasOne.new('id', 'contactable_id', -> (ids, obj, args, ctx) {
    Contact.where(contactable_id: ids, contactable_type: 'Supplier')
  }) do
    type Types::ContactType
  end
  field :products, function: Functions::FindAll.new(Product, -> (obj, args, ctx) {
    obj.products
  }) do
    type types[Types::ProductType]
    argument :filter, Types::ProductFilterType
  end
end

Server-side REST wrapper

You can use GraphQL::Function to write a server-side REST wrapper. Here is example for Fixer.io "Foreign exchange rates and currency conversion API"

class Functions::CurrencyRates < GraphQL::Function
  attr_reader :type

  def initialize
    @type = GraphQL::ObjectType.define do
      name "CurrencyRates"

      field :base, types.String
      field :date, Types::DateType, resolve: ->(obj, args, ctx) { Date.iso8601(obj['date']) }
      field :rates, Types::JSONType
    end
  end

  argument :date, Types::DateType
  argument :base, types.String, default_value: 'EUR'

  def call(obj, args, ctx)
    params = "#{args['date']||'latest'}?base=#{args['base']}"
    response = HTTParty.get("http://api.fixer.io/#{params}", timeout: 10)
    OpenStruct.new(response.parsed_response)
  end
end

Query

{
  currencyRates(date: "2017-10-02", base: "EUR") {
    date
    base
    rates
  }
}

Tracking Schema with GraphQL IDL Schema Dump

To update GraphQL IDL Schema dump with rake task:

rake graphql:schema

See Tracking Schema Changes With GraphQL-Ruby

TODO

  • authorization
  • testing
  • file upload
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].