- 投稿日:2022-02-14T22:25:03+09:00
exitedになったコンテナを丸ごと削除する方法
方法 exitedになっていらないコンテナを丸ごと削除するとき用のメモ $ docker rm $(docker ps -a --filter 'status=exited' -q) docker ps -a --filter 'status=exited' -qでtatusがexitedなもののコンテナIDのみ出力させてます。
- 投稿日:2022-02-14T21:57:20+09:00
dockerでの環境構築時に出る、PHP Fatal error: require(): Failed opening required '/var/www/public/../vendor/autoload.php' の解決方法
皆様こんにちは。 本日新しい会社に転職したのですが、その際に開発環境を構築していて、沼にはまったので、その時のことを備忘録として残そうと思います。 エラーログ [error] 31#31: *3 FastCGI sent in stderr: PHP message: PHP Fatal error: require(): Failed opening required'/var/www/public/../vendor/autoload.php' エラー文の意味 vender/autoload.phpを開こうとしたが、失敗した。 対処方法 docker-compose exec php bash # php用のコンテナを用意していたため php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');" sudo mv composer.phar /usr/local/bin/composer composer -V composer install 解説 まず、phpのコンテナ内のbashに入る。 その後、https://getcomposer.org/download/ に従って、composerをインストールする。 インストール後、composerにパスを通し、 composer -Vでcomposerがインストールされていることを確認する。 最後に、composer installを行って、他のライブラリをインストールする。 最後に 用意されていたDockerfileだと、composerをインストールするコマンドが書いてあったのに、何故かcomposerがインストールされなかった。。 他の人も同様のDockerfileでうまくいっていたようなので、原因は不明。(もしわかったらこの記事に追記します。)
- 投稿日:2022-02-14T19:25:54+09:00
Dockerでファイルの読み取りがフリーズする
事象 DockerのVolumeでホストと共有しているファイルを削除する、リネームする(あるいは編集だけでも?)と、フリーズ、あるいは読み取りがロックされているかのような挙動が発生する(下記参照)。 ブラウザから当該ファイルを取得しようとすると、そのファイルがずっとpendingになって取得できない。 コンテナの中に入って当該ファイルを確認しようとしても、そのファイルがあるディレクトリでlsコマンドを打つと結果がずっと返ってこない。 docker-compose downなどしても、結果が返ってこずタイムアウトする。 Dockerを再起動する以外に解決方法はない。 環境はこんな感じ。 macOS Big Sur 11.5.1 Docker Desktop 4.5.0 対策 原因はさっぱりですが・・・Docker DesktopのPreferences→Generalで、「Use gRPC FUSE for file sharing」のチェックを入れると治ります。
- 投稿日:2022-02-14T17:22:10+09:00
突然Docker上のMySQLに接続できなくなるが再起動をすると治る
結論 ipv6で接続する。 Javaで接続する場合はjdbcの設定を以下のようにする jdbc:mysql://address=(protocol=tcp)(host=::1)(port=3306)(user=root)/db 事象 Docker上のMySQLにしばらく接続していると、何かのタイミングでMySQLへの接続がけられるようになる。 エラーは以下の通り access denied for user 'root'@'localhost' MySQL Workbenchではなぜか接続できる OSを再起動してもなぜか接続できる ゲストOSを落とすとエラーは変わる 127.0.0.1で設定してみてもダメ Dockerの再起動でもダメ ググってみてもrootの権限が足りないだのなんだの…こちとらさっきまで接続できていたんじゃい! 原因 根本原因がわからん…だれかデバッグ方法教えてくれ ただネットワークがらみっぽい感じではある。 127.0.0.1でだめな理由は多分localhostに勝手に読み替えられていたのだと思う。 対応 ipv6で指定することで無事接続ができた。 なんでやねん…。
- 投稿日:2022-02-14T11:31:23+09:00
Golangで実装したAPIをCloud Runにデプロイする
本記事の内容 Go言語で実装したAPIをCloud Runにデプロイする gcloud cliのインストール artifact registryへのdocker imageのpush はてなブログにて掲載しています。
- 投稿日:2022-02-14T11:05:35+09:00
Dockerを起動したら、docker-usersをグループにいれてと言われたときの対処方法
Windows11でDocekrをインストールして、こんなメッセージがでてしまい、 Dockerが起動できない状況に遭遇しました。回避策を自分用にメモを残します。 調べてみたところ、 コマンドプロンプトを管理者として実行し、下記コマンドを実行することでグループに追加させることができるようです。 net localgroup docker-users user /ADD 上記の意味は、ローカルユーザーのuserにdocker-usersを追加する。 userのところを適宜変更して頂くと良いかと思います。 【余談】 コンピュータの管理から、ローカルユーザーとグループ(ローカル)を GUIで編集している解説は見つかるのですが自分のWindowsでは、 コンピュータの管理にローカルユーザーとグループ(ローカル)は 表示されていなかったので、この方法では解決できませんでした。 Windowsキー+Rで、lusrmgr.msiを起動してみたら、 Windows10以降は使用できませんとのこと。 その後、コントロールパネルのユーザーアカウントなどいろいろGUIを見てみましたが ローカルユーザーをグループに追加する方法がみつからず、 コマンドラインでグループにローカルユーザーを追加する方法が見つかったので、 自分のメモとして記載しておくことにしました。 引用サイト https://teratail.com/questions/362607 https://qiita.com/toro_ponz/items/d75706a3039f00ba1205 https://win2012r2.com/2021/05/19/%E3%80%8C%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%A8%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%80%8D%E3%81%AE%E9%96%8B%E3%81%8D%E6%96%B9/
- 投稿日:2022-02-14T10:16:06+09:00
Docker Desktopの代替品使ってみた (Mac)
3年ぶりくらいにContainerの世界に戻ってきたら、いつの間にかDocker Desktopが商用だとfreeで使えなくね?ってなったので、代替品を探していたら、Rancher Desktopを発見しました。 で早速、乗り換えのために試して、エラーにハマったための備忘録がわりの記事となります。 インストール環境 MacBook Pro (13-inch, M1, 2020)、macOS Monterey 12.1 チップ : Apple M1 メモリ : 16 GB インストール作業 すでにインストール済みのDocker Desktopを削除 公式サイトから、dmgファイルをダウンロードして実行。 インストール時には、Moby(dockerd)を指定。 ハマった部分① 立ち上がった、Rancher Desktopの設定内容を確認中、下記のエラーを見つけました。 FAQのページを参照していると、下記の記述がありました。 Q: The tools on the Support Utilities page are not installed and I see a Insufficient permission to manipulate /usr/local/bin error, how do I fix it? A: This occurs when you do not have ownership of /usr/local/bin. A long-term solution to improve the handling of permissions is in the works. In the meantime, a temporary workaround is to change ownership of /usr/local/bin by running sudo chown $USER /usr/local/bin. When you are able to write to the directory, Rancher Desktop is able to create the symlinks. というわけで、テンポラリーのワークアラウンドとして、コマンド実行して権限をちょっと変更することでエラーが解消されます。 ハマった部分② コンソールからdockerを実行してみても見つからない。 % which docker docker not found /usr/local/binの内容を確認していると、どうやら、まだDocker Desktopの内容を参照しているようだったので、/usr/local/bin内の不要な(Docker.Appsを参照している)コマンドたちを削除。 確かに、上のPermissionエラーの画面でも、 Already linked to /Application/Docker.app/Contents/Resources/bin/docker とか書いてるから、不要なものが残っているみたいです。 その後、Rancher Desktopから、シンボリックリンクを作成するようにチェックしていくことでエラーが解消。 上記画像のコマンドについてシンボリックリンクを作成するので、docker-composeなどは存在しない。 動作確認 とりあえず、hello-worldで動作確認。 % docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 93288797bd35: Pull complete Digest: sha256:507ecde44b8eb741278274653120c2bf793b174c06ff4eaa672b713b3263477b Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (arm64v8) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ さて、少しずつリハビリしていこう。
- 投稿日:2022-02-14T10:03:04+09:00
WSL2(Ubuntu)上でのDockerの起動
個人用メモ WSL2(Ubuntu)上でのDockerの起動 sudo service docker start Dockerの起動確認 sudo docker run --rm hello-world
- 投稿日:2022-02-14T00:59:55+09:00
ローカル環境で開発するときに、MySQL を Docker で動かしてみる
はじめに 手元の開発環境でプログラムを開発するときに、MySQL に接続したくなる時が有ります。クラウド上でのマネージドサービスを使ってもよいのですが、費用など掛かるためローカルで MySQL を動かしたくなります。そこで、Docker を使って MySQL を動作させる方法がかなりお手軽だと思います。 この記事では、ローカルで MySQL を動かしたうえで、Go言語から接続する手順を残しておきます。 Docker で MySQL を動かす ECR Public で公開されている Docker Image を使って、ローカル上で MySQL を動かします。Docker Hub でもよいのですが、スロットリングの上限が自分の場合は 6時間につき 100 が上限となっているため、ECR Public を使っていきます。 docker run のコマンド一発でローカル環境で MySQL が動作できます。コンテナサイコー。 MySQL 8.0 を利用 MySQL のパスワードなどを指定 docker run \ --name mydb \ -itd \ --hostname my-mysql \ -e MYSQL_ROOT_PASSWORD=mypassword \ -e BIND-ADDRESS=0.0.0.0 \ -p 3306:3306 \ public.ecr.aws/docker/library/mysql:8.0 なお、ここで動作した MySQL コンテナを削除する場合は次のコマンドで削除可能です。 docker kill mydb docker rm mydb MySQL が正常に稼働しているか、接続テストを行います。 mysql -u root -h 127.0.0.1 --port=3306 -pmypassword 実行例です。問題なく接続できました。 > mysql -u root -h 127.0.0.1 --port=3306 -pmypassword mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.28 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SHOW DATABASES でデータベース一覧も確認してみましょう。正常に見えていますね。 mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec) mysql> テスト用のデータを格納 テスト用のデータ格納します。 CREATE DATABASE sugi01; USE sugi01; CREATE TABLE sample( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(10) NOT NULL, PRIMARY KEY (id) ); INSERT INTO sample(name) VALUES ("MySQLのデータ"); 確認 SELECT * FROM sugi01.sample; 実行例 mysql> SELECT * FROM sugi01.sample; +----+-------------------+ | id | name | +----+-------------------+ | 1 | MySQLのデータ | +----+-------------------+ 1 row in set (0.00 sec) mysql> 環境変数の設定 Go言語をつかって動作確認をしていくのですが、接続先の情報は環境変数として渡したいと思います。環境変数化しておくと、なにかと便利です。 Bash Bash の場合の設定例 export MYSQL_HOSTNAME=localhost export MYSQL_PORT=3306 export MYSQL_USERNAME=root export MYSQL_PASSWORD=mypassword Fish Fish の場合の設定例 set -x MYSQL_HOSTNAME localhost set -x MYSQL_PORT 3306 set -x MYSQL_USERNAME root set -x MYSQL_PASSWORD mypassword Go から接続 Go 言語用プロジェクト用のディレクトリを作成します。 mkdir ~/godir/app-runner-testapp cd ~/godir/app-runner-testapp MySQL 接続用のライブラリを取得します。 go get -u github.com/go-sql-driver/mysql Goの動作確認用プログラム。このコードは、エラーのハンドリングはまったくしていないので、本番環境での利用はだめです。 MySQL の接続先に環境変数を利用 1行分のみのデータを取得して、標準出力にプリント package main import ( "database/sql" "os" "time" _ "github.com/go-sql-driver/mysql" ) func main() { mysql_hostname := os.Getenv("MYSQL_HOSTNAME") mysql_port := os.Getenv("MYSQL_PORT") mysql_username := os.Getenv("MYSQL_USERNAME") mysql_password := os.Getenv("MYSQL_PASSWORD") db, err := sql.Open("mysql", mysql_username+":"+mysql_password+"@tcp("+mysql_hostname+":"+mysql_port+")/sugi01") if err != nil { println("MySQL のコネクション接続に失敗") panic(err) } defer db.Close() // See "Important settings" section. db.SetConnMaxLifetime(time.Minute * 3) db.SetMaxOpenConns(10) db.SetMaxIdleConns(10) row := db.QueryRow(`select * from sample`) var id, name string row.Scan(&id, &name) println(name) } Go の依存関係を管理するための go.mod を生成 go mod init github.com/Sugi275/app-runner-testapp 動作確認 それでは動作確認をしてみましょう。「MySQLのデータ」と表示されており、正常に表示されることがわかります。 > go run app.go MySQLのデータ
- 投稿日:2022-02-14T00:07:53+09:00
Rails7のapiモードでGraphQLを使ってみた
目的 Rails で GraphQL を使うときはどんな感じに書くのかを確認する 必要なもの Docker(今回使用バージョン: Docker version 20.10.12, build e91ed57) VSCode(Remote Develpment 拡張機能を使用, 今回使用バージョン: Version: 1.64.1) ブラウザ(今回は Chrome バージョン: 98.0.4758.80(Official Build) を使用) 開発環境構築 VSCode を起動して Dockerfile を作成し仮想環境を起動する VSCode で開発用の空フォルダを開く(ここでは /dev/rails_graphql とする) Ruby 環境の Dokerfile を作成する /dev/rails_graphsql/Dockerfile FROM ruby VSCode のコマンド Reopen in Container で From Dockerfile から仮想環境に切り替える rails インストール用の Gemfile を作成する /Gemfile source "https://rubygems.org" gem 'rails' VSCode の terminal を開き gem をインストールする terminal bundle install ruby と rails のバージョン確認 terminal ruby -v 実行結果 ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux] terminal rails -v 実行結果 Rails 7.0.2.2 rails プロジェクトを作成 terminal rails new --api --minimal . 動作確認 サーバ起動 terminal rails s http://localhost:3000 にアクセスすれば rails が動作しているのが確認できます GraphQL 用の gem を追加 terminal bundle add graphql bundle add --group development graphiql sass-rails ※ graphiql は開発用ツール, sass-rails は graphiql 動作に必要 graphql 関連ファイルの生成 terminal rails g graphql:install graphiql が動作するよう設定を調整 セッション有効化 application.rb に2行追加 config/application.rb config.middleware.use ActionDispatch::Cookies config.middleware.use ActionDispatch::Session::CookieStore route に設定を追加 routes.rb if Rails.env.development? mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql" end 動作確認 rails s でサーバを起動して http://localhost:3000/graphiql にアクセス テスト用に生成されているクエリを実行 GraphQL のクエリ作成 今回はイベント予定表のAPIを想定して作ってみます まずイベントの予定を管理するモデルと REST API を生成します terminal rails g scaffold Event title:string:index start_at:datetime:index end_at:datetime place:string:index tags:string memo:text canceled:boolean:index 生成結果 invoke active_record create db/migrate/20220213115441_create_events.rb create app/models/event.rb invoke test_unit create test/models/event_test.rb create test/fixtures/events.yml invoke resource_route route resources :events invoke scaffold_controller create app/controllers/events_controller.rb invoke resource_route invoke test_unit create test/controllers/events_controller_test.rb 次に参加者分を生成します terminal rails g scaffold Member name:string:index email:string:uniq 生成結果 invoke active_record create db/migrate/20220213115747_create_members.rb create app/models/member.rb invoke test_unit create test/models/member_test.rb create test/fixtures/members.yml invoke resource_route route resources :members invoke scaffold_controller create app/controllers/members_controller.rb invoke resource_route invoke test_unit create test/controllers/members_controller_test.rb 最後にイベントの参加者分を生成します terminal rails g scaffold EventMember event:references member:references presented:boolean:index 生成結果 invoke active_record create db/migrate/20220213115822_create_event_members.rb create app/models/event_member.rb invoke test_unit create test/models/event_member_test.rb create test/fixtures/event_members.yml invoke resource_route route resources :event_members invoke scaffold_controller create app/controllers/event_members_controller.rb invoke resource_route invoke test_unit create test/controllers/event_members_controller_test.rb not null や 既定値を追加設定します db/migrate/20220213115441_create_events.rb class CreateEvents < ActiveRecord::Migration[7.0] def change create_table :events do |t| t.string :title, null: false t.datetime :start_at, null: false t.datetime :end_at t.string :place t.string :tags t.text :memo t.boolean :canceled, null: false, default: false t.timestamps end add_index :events, :title add_index :events, :start_at add_index :events, :place add_index :events, :canceled end end db/migrate/20220213115747_create_members.rb class CreateMembers < ActiveRecord::Migration[7.0] def change create_table :members do |t| t.string :name, null: false t.string :email, null: false t.timestamps end add_index :members, :name add_index :members, :email, unique: true end end db/migrate/20220213115822_create_event_members.rb class CreateEventMembers < ActiveRecord::Migration[7.0] def change create_table :event_members do |t| t.references :member, null: false, foreign_key: true t.boolean :presented, null: false, default: false t.timestamps end add_index :event_members, :presented end end migration を実行します terminal rails db:migrate 実行結果 == 20220213115441 CreateEvents: migrating ===================================== -- create_table(:events) -> 0.0098s -- add_index(:events, :title) -> 0.0016s -- add_index(:events, :start_at) -> 0.0016s -- add_index(:events, :place) -> 0.0015s -- add_index(:events, :canceled) -> 0.0015s == 20220213115441 CreateEvents: migrated (0.0166s) ============================ == 20220213115747 CreateMembers: migrating ==================================== -- create_table(:members) -> 0.0125s -- add_index(:members, :name) -> 0.0014s -- add_index(:members, :email, {:unique=>true}) -> 0.0015s == 20220213115747 CreateMembers: migrated (0.0157s) =========================== == 20220213115822 CreateEventMembers: migrating =============================== -- create_table(:event_members) -> 0.0138s -- add_index(:event_members, :presented) -> 0.0013s == 20220213115822 CreateEventMembers: migrated (0.0154s) ====================== GraphQL 用の型を生成 terminal rails g graphql:object Event 実行結果 create app/graphql/types/event_type.rb 以下のように events テーブルから情報を取得して自動生成できていますね app/graphql/types/event_type.rb # frozen_string_literal: true module Types class EventType < Types::BaseObject field :id, ID, null: false field :title, String, null: false field :start_at, GraphQL::Types::ISO8601DateTime, null: false field :end_at, GraphQL::Types::ISO8601DateTime field :place, String field :tags, String field :memo, String field :canceled, Boolean, null: false field :created_at, GraphQL::Types::ISO8601DateTime, null: false field :updated_at, GraphQL::Types::ISO8601DateTime, null: false end end 同じように member, event_member の分も生成します。 terminal rails g graphql:object Member 実行結果 create app/graphql/types/member_type.rb terminal rails g graphql:object EventMember 実行結果 create app/graphql/types/event_member_type.rb Event 全件取得の GraphQL クエリを追加 app/graphql/types/query_type.rbへ以下を追加 field :events, [Types::EventType], null: false def events Event.all end graphiql で動作確認 rails s でサーバを起動して、 http://localhost:3000/graphiql にアクセスします event の id, title, startAt(start_atだとエラーになる) を取得するクエリを実行 クエリ { events { id title startAt } } まだデータが一件もないので空の配列になっています テストデータを rails c で投入 terminal rails c rails_console Event.create! title: '勉強会', start_at: '2022/02/18 19:00', end_at: '2022/02/18 21:00' 実行結果 (13.6ms) SELECT sqlite_version(*) TRANSACTION (0.1ms) begin transaction Event Create (19.8ms) INSERT INTO "events" ("title", "start_at", "end_at", "place", "tags", "memo", "canceled", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) [["title", "勉強会"], ["start_at", "2022-02-18 19:00:00"], ["end_at", "2022-02-18 21:00:00"], ["place", nil], ["tags", nil], ["memo", nil], ["canceled", 0], ["created_at", "2022-02-13 13:05:15.499816"], ["updated_at", "2022-02-13 13:05:15.499816"]] TRANSACTION (45.7ms) commit transaction => #<Event:0x00007f680970b048 id: 1, title: "勉強会", start_at: Fri, 18 Feb 2022 19:00:00.000000000 UTC +00:00, end_at: Fri, 18 Feb 2022 21:00:00.000000000 UTC +00:00, place: nil, tags: nil, memo: nil, canceled: false, created_at: Sun, 13 Feb 2022 13:05:15.499816000 UTC +00:00, updated_at: Sun, 13 Feb 2022 13:05:15.499816000 UTC +00:00> 再度 graphql クエリ実行 投入したデータが返ってきますね 登録用の Mutation を作成 Mutation 用のファイルを生成 terminal rails g graphql:mutation CreateEvent 実行結果 create app/graphql/mutations/create_event.rb 以下のファイルが生成されました /app/graphql/mutations/create_event.rb module Mutations class CreateEvent < BaseMutation # TODO: define return fields # field :post, Types::PostType, null: false # TODO: define arguments # argument :name, String, required: true # TODO: define resolve method # def resolve(name:) # { post: ... } # end end end これを修正します /app/graphql/mutations/create_event.rb修正後 module Mutations class CreateEvent < BaseMutation field :event, Types::EventType, null: false argument :title, String, required: true argument :start_at, GraphQL::Types::ISO8601DateTime, required: true argument :end_at, GraphQL::Types::ISO8601DateTime, required: false argument :place, String, required: false argument :tags, String, required: false argument :memo, String, required: false def resolve(**args) { event: Event.create!(**args) } end end end Mutation の動作確認 ブラウザで mutation を実行します mutation mutation { createEvent( input:{ title: "合宿" startAt: "2022-02-26T09:00:00Z" endAt: "2022-02-27T18:00:00Z" place: "有馬温泉" tags: "Ruby 合宿 温泉" } ){ event { id title } } } クエリで登録内容を確認してみます query { events { id title startAt endAt place } } 正常に登録できていますね Member 用の Query と Mutation を追加 以下の Query を追加します /app/graphql/types/query_type.rbへ追加 field :members, [Types::MemberType], null: false def members Member.all end ブラウザで Query の確認をします query { members { id name email } } Mutation を追加します terminal rails g graphql:mutation CreateMember 実行結果 create app/graphql/mutations/create_member.rb Mutation ファイルを修正します。 app/graphql/mutations/create_member.rb修正後 module Mutations class CreateMember < BaseMutation field :member, Types::MemberType, null: false argument :name, String, required: true argument :email, String, required: true def resolve(**args) { member: Member.create!(**args) } end end end ブラウザで Mutation の確認をします mutation mutation { createMember( input:{ name: "山田 太郎" email: "yamada.taro@example.com" } ){ member { id name email } } } イベント参加者の Query と Mutation を作成します Event と Member は 多対多の関係にあるので先に Model クラスに関連を設定しておきます。 /app/models/event.rb class Event < ApplicationRecord has_many :event_members has_many :members, through: :event_members end /app/models/member.rb class Member < ApplicationRecord has_many :event_members has_many :events, through: :event_members end 先に event_members にデータを投入しておきます terminal rails c rails_console Member.create! name: '鈴木 花子', email: 'suzuki.hanako@example.com' rails_console Event.first.then{|event| Member.all.each {|member| event.event_members.create! member: }} 実行結果 Event Load (2.0ms) SELECT "events".* FROM "events" ORDER BY "events"."id" ASC LIMIT ? [["LIMIT", 1]] Member Load (2.0ms) SELECT "members".* FROM "members" TRANSACTION (0.1ms) begin transaction EventMember Create (21.4ms) INSERT INTO "event_members" ("event_id", "member_id", "presented", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["event_id", 1], ["member_id", 1], ["presented", nil], ["created_at", "2022-02-13 13:57:02.526484"], ["updated_at", "2022-02-13 13:57:02.526484"]] TRANSACTION (8.1ms) commit transaction TRANSACTION (0.1ms) begin transaction EventMember Create (27.6ms) INSERT INTO "event_members" ("event_id", "member_id", "presented", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["event_id", 1], ["member_id", 2], ["presented", nil], ["created_at", "2022-02-13 13:57:02.561104"], ["updated_at", "2022-02-13 13:57:02.561104"]] TRANSACTION (8.0ms) commit transaction => [#<Member:0x00007efedf8ebfb8 id: 1, name: "山田 太郎", email: "yamada.taro@example.com", created_at: Sun, 13 Feb 2022 13:36:46.345436000 UTC +00:00, updated_at: Sun, 13 Feb 2022 13:36:46.345436000 UTC +00:00>, #<Member:0x00007efedf8ebec8 id: 2, name: "鈴木 花子", email: "suzuki.hanako@example.com", created_at: Sun, 13 Feb 2022 13:55:30.446672000 UTC +00:00, updated_at: Sun, 13 Feb 2022 13:55:30.446672000 UTC +00:00>] GraphQLのクエリを追加します /app/graphql/types/event_type.rbへ追加 field :members, [Types::MemberType], null: false /app/graphql/types/member_type.rbへ追加 field :events, [Types::EventType], null: false ブラウザで動作確認します query { members { id name email events { id title startAt } } } query { events { id title startAt members { id name email } } } member ごとの events や event ごとの members が取得できていますね Mutation の修正 event 登録時に参加者も指定できるよう Mutation を修正します /app/graphql/mutations/create_event.rb module Mutations class CreateEvent < BaseMutation field :event, Types::EventType, null: false argument :title, String, required: true argument :start_at, GraphQL::Types::ISO8601DateTime, required: true argument :end_at, GraphQL::Types::ISO8601DateTime, required: false argument :place, String, required: false argument :tags, String, required: false argument :memo, String, required: false argument :member_ids, [Integer], required: false def resolve(member_ids:, **args) event = Event.create!(**args).tap do|event| member_ids.each{|member_id| event.event_members.create! member_id: } end { event: } end end end ※ argument :member_ids...の行追加と def resolve を修正しています 動作確認 mutation mutation { createEvent( input: {title: "懇親会", startAt: "2022-02-23T19:00:00Z", memberIds: [1, 2]} ) { event { id title members { id name email } } } } うまくできました Queryに抽出条件を追加 events, members の Query に id 指定できるように query_type.rb を修正します /app/graphql/types/query_type.rbを修正 module Types class QueryType < Types::BaseObject # Add `node(id: ID!) and `nodes(ids: [ID!]!)` include GraphQL::Types::Relay::HasNodeField include GraphQL::Types::Relay::HasNodesField # Add root-level fields here. # They will be entry points for queries on your schema. # TODO: remove me field :test_field, String, null: false, description: "An example field added by the generator" def test_field "Hello World!" end field :events, [Types::EventType], null: false do argument :ids, [Integer], required: false end def events(ids: nil) if ids Event.where(id: ids) else Event.all end end field :members, [Types::MemberType], null: false do argument :ids, [Integer], required: false end def members(ids: nil) if ids Member.where(id: ids) else Member.all end end end end field :events, と fields :members にブロックをつけて受け入れる引数を追加し、メソッド内で引数が指定されている場合は抽出条件を指定するようにしました 引数は ids: nil とすれば省略可能になります さいごに 使った感想としては REST API を作るよりコード量は少なくてすみそうなのと、エンドポイントは1つだけなので散らからないところが良いと思いました。