Query Serviceとは、検索に特化したドメインサービスです。

Query Serviceには二種類あります。

下記のテストを見てください。

val employee = Employee.mock() 
repository.add(employee)

val expect = listOf(employee)

val actual = queryService.resolveAll()

assertEquals(expect,actual)

ここでは、Repositoryを使ってデータを追加したものはQuery Serviceの検索対象になっていることとします。

このテストを失敗するQuery Serviceと、成功するQuery Serviceが存在します。

これはQuery Serviceの実装方法によって変わってきます。

classDiagram
direction TB

class employee{
	UUID employee_id PK
	timestamp created_at
}

class employee_value1{
	UUID employee_id FK
	text value1
	timestamp created_at
}
employee <|-- employee_value1

class employee_value2{
	UUID employee_id FK
	text value2
	timestamp created_at
}
employee <|-- employee_value2

class employee_query{
	UUID employee_id FK
	text value1
	text value2
	timestamp created_at
}
employee <|-- employee_query

上記の例では、query用のテーブル(employee_query、以降queryテーブル)を用意しvalueを保存しています。

これだけ見るとQuery Serviceの必要性は無いように見えますが、複数の社員を検索したり、value(氏名等)から検索するときに便利です。

このパターンではRepositoryが呼び出される度にemployee_queryにデータを追加していきます。

EmployeeQueryDaoに専用のメソッドを作り、Query Serviceそのメソッドを呼び出すようにします。

この実装方法では先ほどのテストは成功します。

これを時差なしQuery Serviceと呼びます。

次に下記の例を見てみましょう。

classDiagram
direction TB

class employee{
	UUID employee_id PK
	timestamp created_at
}

class employee_value1{
	UUID employee_id FK
	text value1
	timestamp created_at
}
employee <|-- employee_value1

class employee_value2{
	UUID employee_id FK
	text value2
	timestamp created_at
}
employee <|-- employee_value2

%%
class employee_query_other_than_rdb{
	UUID employee_id
	text value1
	text value2
	timestamp created_at
}

Query Service用のデータを外部のサービスを使って保存しています。

この場合、最初のテストが失敗する可能性があります。