GraphQL 開発における効率的なコード分割と ChatGPT 活用のベストプラクティス #
【目的】 #
GraphQL API を Flask + Graphene で開発する際に、
- 人間開発者にとって保守性・拡張性が高く
- ChatGPT にとっても理解しやすく相談しやすい コード構成と運用方法をまとめたノウハウです。
【基本方針】 #
◆ 本番コード:機能ごとにファイルを分離 #
mutations/
ディレクトリに、Mutation ごとにファイルを分割queries/
ディレクトリに、Query ごとにファイルを分割- 各ファイル内に関連する
InputType
/ObjectType
も同時に定義
◆ ChatGPT に相談するとき:該当処理を 1 ファイルにまとめる #
types.py
のような型共通ファイルは使わず、Mutation と Type をその場にまとめて貼る- 関連する型定義を明示的に含めることで、AI が完全に理解しやすくなる
【ディレクトリ構成例】 #
graphql_schema/
├── __init__.py
├── schema.py # Schema(query=..., mutation=...) の統合定義
├── utils.py # 共通処理(put_item, DynamoDB処理など)
├── mutations/
│ ├── __init__.py # Mutation統合クラス
│ ├── order.py # placeOrder + 型定義
│ ├── reservation.py # reservation + 型定義
│ └── ...
├── queries/
│ ├── __init__.py # Query統合クラス
│ ├── status.py # hello やステータス系のクエリ
│ └── ...
【Mutation / Query のベストプラクティス】 #
◆ Mutation ファイルの例(mutations/order.py
)
#
from graphene import Mutation, String, Int, List, InputObjectType, ObjectType
from graphql_schema.utils import put_item, get_japanese_current_time
from boto3.dynamodb.types import TypeSerializer
import uuid
# --- InputType ---
class OrderItemInput(InputObjectType):
itemId = String(required=True)
name = String(required=True)
quantity = Int(required=True)
price = Int()
class OrderInput(InputObjectType):
tableId = String(required=True)
printerMAC = String(required=True)
items = List(OrderItemInput, required=True)
# --- OutputType ---
class OrderResponse(ObjectType):
jobToken = String()
status = String()
timestamp = String()
# --- Mutation定義 ---
class PlaceOrder(Mutation):
class Arguments:
orderInput = OrderInput(required=True)
Output = OrderResponse
def mutate(self, info, orderInput):
serializer = TypeSerializer()
job_data = {
"printerMAC": serializer.serialize(orderInput["printerMAC"])["S"],
"tableId": serializer.serialize(orderInput["tableId"])["S"],
"items": serializer.serialize(orderInput["items"])["L"],
}
job_token = str(uuid.uuid4())
put_item(
printerMac=orderInput["printerMAC"],
jobToken=job_token,
mediaTypes=["application/vnd.star.starprnt"],
jobBody=job_data,
printType="Order"
)
return OrderResponse(
jobToken=job_token,
status="confirmed",
timestamp=get_japanese_current_time()
)
◆ Query ファイルの例(queries/status.py
)
#
from graphene import ObjectType, String
class StatusQuery(ObjectType):
hello = String(default_value="Hello from print system")
◆ 統合ファイル(mutations/init.py) #
from graphene import ObjectType
from .order import PlaceOrder
from .reservation import Reservation
# ... 他のMutation
class Mutation(ObjectType):
placeOrder = PlaceOrder.Field()
reservation = Reservation.Field()
◆ 統合ファイル(queries/init.py) #
from graphene import ObjectType
from .status import StatusQuery
# ... 他のQuery
class Query(StatusQuery, ObjectType):
pass
【ChatGPT に相談するときの Tips】 #
◆ その Mutation/Query に関する型・処理を1 ファイルで渡す #
class OrderInput(InputObjectType):
...
class PlaceOrder(Mutation):
...
class Mutation(ObjectType):
placeOrder = PlaceOrder.Field()
schema = Schema(mutation=Mutation)
◆ “types.py"などの共通化は ChatGPT には不搬所 #
- ChatGPT は"その場に書かれていない型"の内容は文脈から類推するしかない
- 型定義を明示的に書いた方が確実
【まとめ】 #
- 本番コードでは機能単位でファイルを分割して保守性を高める
- ChatGPT に相談する際は、対象の Mutation や Query に関する型・処理を 1 ファイルにまとめて提示する
- この設計方針なら、開発効率と AI 活用の両方で最適化が可能