【GraphQL】Carelyの過重労働機能のQueryを一部紹介
こんにちは!サーバーサイドエンジニアのメグミです!
今月の頭にCarelyの過重労働機能をリニューアルしました!
今回は、その中で行ったGraphQL化についてQueryを一部を紹介しながら説明したいと思います。
はじめに
過重労働機能とは
人事や産業医が従業員の残業時間や疲労蓄積度を管理するための機能です。
簡単にまとめると以下のような機能があります。
- 残業時間の確認
- 長時間労働者の自動抽出
- 疲労蓄積度チェックテスト
- 残業時間のインポート/エクスポート
- 残業情報のメール送信
今回紹介すること
REST API から GraphQL Ruby での実装に変更
リニューアル前はRESTでの実装でしたが、GraphQLでの実装に変更となりました。
今回はその中の一部Queryの実装をご紹介します。
CarelyのGraphQLの構成
Carely では graphiql-rails
というgemを使用しています。
構成については以下のとおりです。
従業員の残業時間の取得
データの参照は GraphQLのQuery
で行います。
まず、query_type.rb
に field
を定義し、必要に応じて argument
の定義をします。
field名のメソッドを定義し処理を記述します。
# query_type.rb
module Types
class QueryType < Types::BaseObject
field :overtimes, Types::OvertimesType, null: true, description: "当該月の残業時間" do
argument :year, Int, required: true, description: "年"
argument :month, Int, required: true, description: "月"
end
def overtimes(**args)
Queries::OvertimesQuery.new(user: context[:current_user]).policy_scoped_overtimes(args)
end
end
end
上記のQueryが返すのは OvertimesType
という型なので type
を定義します。
# overtimes_type.rb
module Types
class OvertimesType < Types::BaseObject
field :overworker_count, Int, null: true, description: "過重労働者数"
field :customer_count, Int, null: true, description: "従業員数"
field :overtimes, [OvertimeType], null: true, description: "残業時間情報"
end
end
上記の type
にある OvertimeType
も定義します。
# overtime_type.rb
module Types
class OvertimeType < Types::BaseObject
description "残業時間情報"
field :hour, Float, null: true, description: "残業時間"
field :year, String, null: true, description: "年"
field :year_month, Types::Date, null: true, description: "年月"
field :customer, Types::CustomerType, null: true, description: "従業員情報"
end
end
実際の処理(Query Processing)を overtimes_query.rb
に記述します。
# overtimes_query.rb
module Queries
class OvertimesQuery < Queries::BaseObject
def policy_scoped_overtimes(**args)
year_month = Overtime.年月を作成するメソッド(args[:year], args[:month])
monthly_overtimes = Overtimes.where(year_month: year_month)
# 当該年月での過重労働者数
overworker_count = monthly_overtimes.where("hour >= ?", 45).count
# 当該年月での従業員数
customer_count = Customer.joins(:overtimes).merge(monthly_overtimes).count
{
overworker_count: overworker_count,
customer_count: customer_count,
overtimes: overtimes
}
end
end
end
この処理で最終的に返す値はquery_type.rb
で定義した OvertimesType
に合わせます。
overtimes のデータモデルは以下のとおりです。
# overtime.rb
# == Schema Information
#
# Table name: overtimes
#
# id :integer not null, primary key
# hour(残業時間) :decimal(5, 2) default(0.0), not null
# year_month :date not null
# created_at :datetime not null
# updated_at :datetime not null
# customer_id :integer not null
#
# Foreign Keys
#
# fk_rails_... (customer_id => customers.id)
#
class Overtime < ApplicationRecord
belongs_to :customer
# 省略
end
GraphiQL
(/graphiql)でQueryを実行すると残業時間情報を取得することができます。
先ほど query_type.rb
で定義した field
の argument
を指定し実行します。
query {
overtimes(fiscalYear: 2020, month: 4) {
overworkerCount
customerCount
overtimes{
yearMonth
hour
customer{
fullname
}
}
}
}
実行結果が data
として取得できます。
{
"data": {
"overtimes": {
"overworkerCount": 2,
"customerCount": 2,
"overtimes": [
{
"hour": 81,
"customer": {
"email": "employee-101@example.com",
"employeeNumber": "101",
"fullname": "従業員 太郎"
}
},
{
"hour": 80.5,
"customer": {
"email": "employee-201@example.com",
"employeeNumber": "201",
"fullname": "人事 太郎"
}
}
]
}
}
}
さいごに
以上、過重労働機能のGraphQLのQueryの一部を紹介しました!
おわり