使用Rails + React + GraphQL + ApolloClient进行屏幕显示的实践指南!

一开始

你好!初次见面!我是负责第11天日历的佐佐木。

好吧,這次我自己學了後端之後,接下來該怎麼辦呢?我曾經考慮過如果我能學習前端,會不會很酷呢?這樣的思考是很直接的,我一開始就這麼學習。然而,我個人遇到了很多困難,非常辛苦。希望這能對你們有點參考價值。

我希望对于那些想要充分利用Rails的人来说,他们能够看到这个。

关于使用的东西,简而言之解释一下。

Ruby on Rails – 红宝石轨道

众所周知的Ruby on Rails是一种快速且可进行网页开发的优秀选择。

反应

这是一个现代化前端框架之一。
Hooks非常有趣!!
https://ja.reactjs.org/

图形查询语言

用GraphQL替代RESTapi的观念。(如果我理解错了,我很抱歉。)
感觉GraphQL可以更直观地编写代码。
https://graphql.org/

阿波罗客户端

这个是连接React和Rails的工具。
https://www.apollographql.com/docs/react/api/core/ApolloClient/

已完成的文件 (yǐ de

实施

后端开发部分

创建Rails应用程序的模板

让我们立即在终端上输入并创建一个模板。
※这次我们将使用API模式。

$ rails new demo --api

建立模型

我们立即输入cd demo,然后移动到demo目录吧!在移动到目录后,我们可以继续操作。

$ rails g model User name:string age:integer
$ rails g model Book title:string body:text user:references
$ rails db:migrate RAILS_ENV=development

让我们创建并应用User和Book模型。关于参考资料,这里可以提供一些参考信息。

关系的定义

如果能够创建模型,由于Book模型已通过references自动建立了关联,因此我们只需要设置User模型。

class User < ApplicationRecord
  # 以下を記述
  has_many :books
end

安装各种宝石

我们将分别安装以下gem:
graphql → 对于GraphQL开发是必不可少的
graphiql-rails → 允许在rails的开发环境中进行GraphQL的操作验证
faker → 自动创建随机虚拟数据

group :development do
  gem 'listen', '~> 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  # 追加
  gem 'graphiql-rails'
  gem 'faker'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# 追加
gem 'graphql'

如果能够以中文来描述的话

$ bundle install

让我们先做好吧!

GraphQL的安装

為了使用額外添加的GraphQL,只需要佐伯一個選擇。

$ rails g graphql:install

在应用程序文件的根目录下添加与GraphQL相关的内容

Rails.application.routes.draw do
  # 以下の部分が自動で追加されている
  post "/graphql", to: "graphql#execute"
end

以下是一种可以在终端上处理以下命令的方法。

Graphql:
  graphql:enum
  graphql:install
  graphql:interface
  graphql:loader
  graphql:mutation
  graphql:object
  graphql:scalar
  graphql:union

创建虚拟数据

利用先刚才安装的faker

10.times do
  user = User.create!(name: Faker::Name.name, age: rand(1..100))
  10.times do
    user.books.create!(title: Faker::Lorem::sentence(word_count: 5),
                       body: Faker::Lorem::paragraph(sentence_count: 4))
  end
end

作为

$ rails db:seed
$ rails c # コンソール画面へ
irb(main):001:0> User.all
   10個のUser情報の表示
irb(main):002:0> Book.all
   10個のBook情報の表示
irb(main):003:0> exit

如果可以进行确认,就能知道数据是否正确输入!

创建GraphQL对象

我們首先在終端中創建一個 GraphQL 物件。

$ rails g graphql:object user
$ rails g graphql:object book

我想你可以通过这样描述,app/graphql/types直接下会生成一个对象名为(对象名)_type.rb的文件。

确认和添加类型文件

这里的类型定义与迁移文件的描述方法有些相似。让我们进行确认和追加。

module Types
  class UserType < Types::BaseObject
    field :id, ID, null: false
    field :name, String, null: true
    field :age, Integer, null: true
    field :created_at, GraphQL::Types::ISO8601DateTime, null: false
    field :updated_at, GraphQL::Types::ISO8601DateTime, null: false

    # ここから記述
    field :books, [Types::BookType], null: false
    field :books_object_count, Integer, null: false

    # ユーザーに紐づけられたBookオブジェクトの数を数える
    def books_object_count
      object.books.count
    end
  end
end
module Types
  class BookType < Types::BaseObject
    field :id, ID, null: false
    field :title, String, null: true
    field :body, String, null: true
    field :user_id, Integer, null: false
    field :created_at, GraphQL::Types::ISO8601DateTime, null: false
    field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
  end
end

查询的定义

我认为简单地解释查询就是获取数据的操作,这个理解是正确的。
※ 作为补充说明,因为这里只获取一个数据,所以不需要用数组括起来。

module Types
  class QueryType < Types::BaseObject
    # 全てのデータの取得
    field :users, [Types::UserType], null: false
    def users
      User.all
    end

    # 引数の番号のデータを取得
    field :user, Types::UserType, null: false do
      argument :id, ID, required: true
    end
    def user(id:)
      User.find(id)
    end
  end
end

使得在Rails中能够查看Graphql。

如果你到了这一步,那就实际确认一下吧。试着实际访问“实际”并打开GraphQL的界面。

Rails.application.routes.draw do
  # ここの部分を記述
  if Rails.env.development?
    mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: "graphql#execute"
  end

  # 以下の部分が自動で追加されている
  post "/graphql", to: "graphql#execute"
end

描述

require_relative 'boot'

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie" # ここの部分のコメントアウトを取る
require "rails/test_unit/railtie"

另外,在app文件夹的根目录下创建assets/config/manifest.js。

//= link graphiql/rails/application.css
//= link graphiql/rails/application.js

在開發環境中,只有透過該設定才能進行訪問。

スクリーンショット 2020-12-03 8.39.51.png

我要查看数据。

如果能做到这一步,我们来实际确认一下数据吧!

所有的数据
スクリーンショット 2020-12-03 11.28.05.png
指定的数据
スクリーンショット 2020-12-03 11.30.02.png

前端编程

创建前端模板

让我们开始创建React的模板吧。
这次我们将使用create-react-app来快速创建React应用。

$ yarn global add create-react-app #create-react-appコマンドをグローバルで使用できるようにする
$ create-react-app front-demo #雛形を作成

CORS的配置

CORS在服务器过滤CRUD请求的操作被称为认证!
请参考此网站。
由于默认处于注释状态,因此请进行注释处理!

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
gem 'rack-cors' #コメントアウト

在进行bundle install之后。

# Be sure to restart your server when you modify this file.

# Avoid CORS issues when API is called from the frontend app.
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.

# Read more: https://github.com/cyu/rack-cors

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

就这样吧。

在屏幕上显示
スクリーンショット 2020-12-10 17.28.47.png

用于每个项目中,请安装上述所提到的软件。
同时请注意保留默认创建的App.js文件。

import React from 'react';
import ApolloClient from 'apollo-boost'
import { ApolloProvider } from "@apollo/react-hooks"
import Demo from "./Demo";
const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql'
})

const App = () => {
    return (
        <ApolloProvider client={client} >
            <div className="App">
                <Demo/>
            </div>
        </ApolloProvider>
    );
}

export default App;

请创建一个名为Demo.js的文件,放在src文件夹中。

import React from 'react';
import {useQuery} from '@apollo/react-hooks';
import gql from 'graphql-tag';

const GET_USERS = gql`
    {
        users{
            id
            name
            age
            books{
                id
                title
                body
            }
        }
    }
`;

const Demo = () => {
    const {loading, error, data} = useQuery(GET_USERS);
    const style = {
        color: "red"
    };

    if (loading) return 'ロード中....';
    if (error) return `Error ${error.message}`;
    return (
        <React.Fragment>
            {data.users.map(user => (
                <div key={user.id}>
                    <h1>{user.name}</h1>
                    <h2>{user.age}</h2>
                    {user.books.map(book => (
                        <div key={book.id}>
                            <h1>{book.title}</h1>
                            <h2>{book.body}</h2>
                        </div>
                    ))};
                    <h1 style={style}>ここまでが{user.id}回目!</h1>
                </div>
            ))}

        </React.Fragment>
    )
};

export default Demo;

让我们这么做吧!

在屏幕上确认

スクリーンショット 2020-12-10 17.26.39.png

这是一个实施的示例!

我认为您可以进一步扩展GET_USER和创建用户等功能,所以请在方便的时候尝试一下。

感谢您阅读文章!!!

bannerAds