Shared Types & GraphQL Codegen Pipeline
Objective
Create shared types package and establish GraphQL code generation pipeline for type-safe client-server communication.
Background
Shared types ensure consistency between web, mobile, and API. The codegen pipeline keeps types synchronized with the database schema.
Tasks
-
Create packages/shared structure -
Define core business types -
Set up GraphQL schema export from PostGraphile -
Configure code generation for ReasonML types -
Create utility functions for type conversions -
Add validation functions -
Document type usage patterns
Package Structure
packages/shared/
├── lib/
│ ├── dune
│ ├── Types.re # Core business types
│ ├── Validation.re # Type validation
│ ├── Converters.re # JSON conversions
│ └── GraphQL.re # Generated types
├── scripts/
│ └── codegen.js # Type generation script
├── schema.graphql # Exported from PostGraphile
├── dune-project
└── package.json
Core Types
(* lib/Types.re *)
type userId = string;
type teamId = string;
type projectId = string;
type user = {
id: userId,
email: string,
name: option(string),
createdAt: Js.Date.t,
};
type task = {
id: string,
title: string,
description: option(string),
status: taskStatus,
priority: priority,
assigneeId: option(userId),
projectId: projectId,
}
and taskStatus =
| Todo
| InProgress
| Done
| Archived
and priority =
| Low
| Medium
| High
| Critical;
Code Generation Pipeline
// scripts/codegen.js
const { generateReasonTypes } = require('./generators');
async function generate() {
// 1. Fetch schema from PostGraphile
const schema = await fetchSchema('http://localhost:5000/graphql');
// 2. Generate ReasonML types
const types = generateReasonTypes(schema);
// 3. Write to lib/GraphQL.re
fs.writeFileSync('lib/GraphQL.re', types);
}
Dune Configuration
(library
(public_name melange-shared)
(name melange_shared)
(libraries melange.js)
(modes melange native)
(preprocess (pps melange.ppx)))
Acceptance Criteria
-
Types compile in both Melange and native modes -
Code generation runs automatically -
Types match PostGraphile schema -
Validation functions work -
JSON serialization/deserialization works -
Can be imported by web and mobile packages
Scripts
{
"scripts": {
"codegen": "node scripts/codegen.js",
"codegen:watch": "nodemon --watch ../api-server/schema.graphql scripts/codegen.js"
}
}
Type Safety Features
-
Variant types for enums -
Option types for nullable fields -
Custom scalar handlers (Date, JSON, etc.) -
Type-safe IDs (userId, teamId, etc.)
Testing
(* test/TypesTest.re *)
let testUserValidation = () => {
let validUser = {id: "1", email: "test@example.com", name: None, createdAt: Js.Date.now()};
assert(Validation.isValidUser(validUser));
};
🟡 High
Priority: Central to type safety across the stack.
Estimated Effort: 2 days
Dependencies
CI Validation
-
Types compile successfully -
Code generation runs without errors -
Tests pass -
Can be imported by other packages