0
# Programmatic API
1
2
The Relay Compiler provides a comprehensive Rust crate API for building custom tooling, integrating with build systems, and extending compilation functionality.
3
4
## Core Dependencies
5
6
To use the programmatic API, add these dependencies to your `Cargo.toml`:
7
8
```toml
9
[dependencies]
10
relay-compiler = "20.1.1"
11
common = { path = "../common" }
12
schema = { path = "../schema" }
13
```
14
15
## Core Configuration Types
16
17
### Config and Project Management
18
19
```rust
20
{ .api }
21
// Main configuration struct
22
pub struct Config {
23
pub projects: Vec<ProjectConfig>,
24
pub feature_flags: FeatureFlags,
25
// Additional configuration fields
26
}
27
28
// Individual project configuration
29
pub struct ProjectConfig {
30
pub name: ProjectName,
31
pub schema_location: SchemaLocation,
32
pub source_set: SourceSet,
33
pub artifact_writer: Box<dyn ArtifactWriter>,
34
// Additional project fields
35
}
36
37
// Project identifier
38
pub struct ProjectName(String);
39
40
// File source categorization
41
pub enum FileSourceKind {
42
Generated,
43
Schema,
44
Source,
45
}
46
47
// Schema file location
48
pub enum SchemaLocation {
49
File(PathBuf),
50
Directory(PathBuf),
51
Url(String),
52
}
53
```
54
55
### Configuration File Types
56
57
```rust
58
{ .api }
59
// Configuration file representation
60
pub enum ConfigFile {
61
SingleProject(SingleProjectConfigFile),
62
MultiProject(MultiProjectConfigFile),
63
}
64
65
// Single project config
66
pub struct SingleProjectConfigFile {
67
pub language: Language,
68
pub src: Option<String>,
69
pub schema: Option<String>,
70
pub artifact_directory: Option<String>,
71
// Additional fields
72
}
73
74
// Multi project config
75
pub struct MultiProjectConfigFile {
76
pub sources: HashMap<String, String>,
77
pub projects: HashMap<String, ProjectConfig>,
78
// Additional fields
79
}
80
```
81
82
## Build System API
83
84
### Core Build Functions
85
86
```rust
87
{ .api }
88
// Build multiple programs
89
pub fn build_programs(
90
config: &Config,
91
source_hashes: &SourceHashes,
92
) -> Result<Programs, BuildProjectFailure>;
93
94
// Build single program
95
pub fn build_raw_program(
96
config: &ProjectConfig,
97
schema: &SDLSchema,
98
) -> Result<Program, Vec<Error>>;
99
100
// Build GraphQL schema
101
pub fn build_schema(
102
schema_location: &SchemaLocation,
103
schema_extensions: &[PathBuf],
104
) -> Result<SDLSchema, Vec<Error>>;
105
106
// Generate output artifacts
107
pub fn generate_artifacts(
108
config: &ProjectConfig,
109
programs: &Programs,
110
) -> Result<Vec<Artifact>, Vec<Error>>;
111
112
// Apply transformations
113
pub fn transform_program(
114
config: &ProjectConfig,
115
program: &Program,
116
) -> Result<Program, Vec<Error>>;
117
118
// Validate generated code
119
pub fn validate(
120
config: &Config,
121
programs: &Programs,
122
) -> Result<(), Vec<ValidationError>>;
123
```
124
125
### Build Types
126
127
```rust
128
{ .api }
129
// Generated artifact representation
130
pub struct Artifact {
131
pub content: ArtifactContent,
132
pub source_file: PathBuf,
133
pub generated_file: PathBuf,
134
}
135
136
// Artifact content types
137
pub enum ArtifactContent {
138
Operation(String),
139
Fragment(String),
140
Request(String),
141
TypeDefinitions(String),
142
}
143
144
// Type generation artifacts
145
pub struct ArtifactGeneratedTypes {
146
pub typescript_types: Option<String>,
147
pub flow_types: Option<String>,
148
}
149
150
// Build failure information
151
pub struct BuildProjectFailure {
152
pub project_name: ProjectName,
153
pub errors: Vec<Error>,
154
}
155
156
// Source file hash tracking
157
pub struct SourceHashes {
158
pub files: HashMap<PathBuf, String>,
159
}
160
```
161
162
### Usage Example
163
164
```rust
165
use relay_compiler::{Config, build_programs, generate_artifacts};
166
167
pub fn compile_project(config: Config) -> Result<(), Box<dyn std::error::Error>> {
168
// Build programs from source
169
let source_hashes = SourceHashes::new();
170
let programs = build_programs(&config, &source_hashes)?;
171
172
// Generate artifacts for each project
173
for project_config in &config.projects {
174
let artifacts = generate_artifacts(project_config, &programs)?;
175
176
// Write artifacts using configured writer
177
for artifact in artifacts {
178
project_config.artifact_writer.write_artifact(&artifact)?;
179
}
180
}
181
182
Ok(())
183
}
184
```
185
186
## Artifact Writer System
187
188
### Writer Trait
189
190
```rust
191
{ .api }
192
// Base trait for artifact output
193
pub trait ArtifactWriter: Send + Sync {
194
fn write_artifact(&self, artifact: &Artifact) -> Result<(), Error>;
195
fn finalize(&self) -> Result<(), Error>;
196
}
197
```
198
199
### Built-in Writers
200
201
```rust
202
{ .api }
203
// Standard file writer
204
pub struct ArtifactFileWriter {
205
pub base_directory: PathBuf,
206
}
207
208
impl ArtifactFileWriter {
209
pub fn new(base_directory: PathBuf) -> Self;
210
}
211
212
// Validation-only writer (no file output)
213
pub struct ArtifactValidationWriter {
214
pub expected_artifacts: Vec<Artifact>,
215
}
216
217
impl ArtifactValidationWriter {
218
pub fn new(expected_artifacts: Vec<Artifact>) -> Self;
219
pub fn validate(&self) -> Result<(), Vec<ValidationError>>;
220
}
221
222
// No-op writer for testing
223
pub struct NoopArtifactWriter;
224
```
225
226
### Custom Writer Example
227
228
```rust
229
use relay_compiler::{ArtifactWriter, Artifact, Error};
230
231
pub struct CustomArtifactWriter {
232
output_handler: Box<dyn Fn(&Artifact) -> Result<(), Error>>,
233
}
234
235
impl ArtifactWriter for CustomArtifactWriter {
236
fn write_artifact(&self, artifact: &Artifact) -> Result<(), Error> {
237
(self.output_handler)(artifact)
238
}
239
240
fn finalize(&self) -> Result<(), Error> {
241
// Custom finalization logic
242
Ok(())
243
}
244
}
245
```
246
247
## File Source System
248
249
### File Source Trait
250
251
```rust
252
{ .api }
253
// Base trait for file source handling
254
pub trait FileSource: Send + Sync {
255
fn watch(&self) -> Result<FileSourceSubscription, Error>;
256
fn scan(&self) -> Result<FileSourceResult, Error>;
257
}
258
259
// File source operation result
260
pub struct FileSourceResult {
261
pub files: Vec<FileGroup>,
262
pub has_changes: bool,
263
}
264
265
// File watching subscription
266
pub struct FileSourceSubscription {
267
pub receiver: Receiver<FileSourceResult>,
268
}
269
```
270
271
### File Types
272
273
```rust
274
{ .api }
275
// Individual file representation
276
pub struct File {
277
pub name: PathBuf,
278
pub content: String,
279
pub kind: FileSourceKind,
280
}
281
282
// Grouped file representation
283
pub struct FileGroup {
284
pub files: Vec<File>,
285
pub base_directory: PathBuf,
286
}
287
288
// File categorization logic
289
pub trait FileCategorizer: Send + Sync {
290
fn categorize(&self, path: &Path) -> FileSourceKind;
291
}
292
```
293
294
### File Source Implementations
295
296
```rust
297
{ .api }
298
// Filesystem source reader
299
pub struct FsSourceReader {
300
pub root_directory: PathBuf,
301
pub excludes: Vec<String>,
302
}
303
304
impl FsSourceReader {
305
pub fn new(root_directory: PathBuf, excludes: Vec<String>) -> Self;
306
}
307
308
// Generic source reader
309
pub struct SourceReader {
310
pub file_source: Box<dyn FileSource>,
311
pub categorizer: Box<dyn FileCategorizer>,
312
}
313
314
// Factory function for file sources
315
pub fn source_for_location(
316
location: &Path,
317
excludes: &[String],
318
) -> Result<Box<dyn FileSource>, Error>;
319
```
320
321
## Operation Persistence API
322
323
### Persistence Trait
324
325
```rust
326
{ .api }
327
// Base trait for query persistence
328
pub trait OperationPersister: Send + Sync {
329
fn persist_operation(
330
&self,
331
operation: &str,
332
query_text: &str,
333
) -> Result<String, Error>;
334
}
335
```
336
337
### Built-in Persisters
338
339
```rust
340
{ .api }
341
// Local file persistence
342
pub struct LocalPersister {
343
pub file_path: PathBuf,
344
pub algorithm: HashAlgorithm,
345
pub include_query_text: bool,
346
}
347
348
impl LocalPersister {
349
pub fn new(
350
file_path: PathBuf,
351
algorithm: HashAlgorithm,
352
include_query_text: bool,
353
) -> Self;
354
}
355
356
// HTTP endpoint persistence
357
pub struct RemotePersister {
358
pub url: String,
359
pub headers: HashMap<String, String>,
360
pub params: HashMap<String, String>,
361
pub concurrency: usize,
362
}
363
364
impl RemotePersister {
365
pub fn new(
366
url: String,
367
headers: HashMap<String, String>,
368
params: HashMap<String, String>,
369
concurrency: usize,
370
) -> Self;
371
}
372
373
// Configuration enum for persistence
374
pub enum PersistConfig {
375
Local(LocalPersistConfig),
376
Remote(RemotePersistConfig),
377
}
378
```
379
380
### Hash Algorithms
381
382
```rust
383
{ .api }
384
pub enum HashAlgorithm {
385
MD5,
386
SHA1,
387
SHA256,
388
}
389
```
390
391
## Status Reporting
392
393
```rust
394
{ .api }
395
// Trait for progress reporting during compilation
396
pub trait StatusReporter: Send + Sync {
397
fn build_starts(&self);
398
fn build_finishes(&self, result: &Result<(), BuildProjectFailure>);
399
fn project_starts(&self, project_name: &ProjectName);
400
fn project_finishes(&self, project_name: &ProjectName, result: &Result<(), Vec<Error>>);
401
}
402
403
// Built-in console reporter
404
pub struct ConsoleStatusReporter;
405
406
impl StatusReporter for ConsoleStatusReporter {
407
// Implementation details
408
}
409
```
410
411
## Utility Functions
412
413
```rust
414
{ .api }
415
// Program compilation helper
416
pub fn get_programs(
417
config: &Config,
418
source_hashes: &SourceHashes,
419
) -> Result<HashMap<ProjectName, Program>, BuildProjectFailure>;
420
421
// GraphQL parser configuration
422
pub fn get_parser_features() -> ParserFeatures;
423
424
// Schema loading utilities
425
pub fn load_schema_from_file(path: &Path) -> Result<SDLSchema, Vec<Error>>;
426
pub fn load_schema_from_string(content: &str) -> Result<SDLSchema, Vec<Error>>;
427
```
428
429
## Error Types
430
431
```rust
432
{ .api }
433
// Main error type
434
#[derive(Debug, thiserror::Error)]
435
pub enum Error {
436
#[error("IO error: {0}")]
437
IO(#[from] std::io::Error),
438
439
#[error("GraphQL error: {0}")]
440
GraphQL(String),
441
442
#[error("Configuration error: {0}")]
443
Config(String),
444
445
#[error("Build error: {0}")]
446
Build(String),
447
}
448
449
// Validation error
450
#[derive(Debug)]
451
pub struct ValidationError {
452
pub message: String,
453
pub file: Option<PathBuf>,
454
pub line: Option<usize>,
455
}
456
```
457
458
## Complete Integration Example
459
460
```rust
461
use relay_compiler::*;
462
use std::path::PathBuf;
463
464
fn main() -> Result<(), Box<dyn std::error::Error>> {
465
// Create configuration
466
let config = Config {
467
projects: vec![ProjectConfig {
468
name: ProjectName::from("web"),
469
schema_location: SchemaLocation::File(PathBuf::from("./schema.graphql")),
470
source_set: SourceSet::new(vec![PathBuf::from("./src")]),
471
artifact_writer: Box::new(ArtifactFileWriter::new(
472
PathBuf::from("./src/__generated__")
473
)),
474
// Additional configuration
475
}],
476
feature_flags: FeatureFlags::default(),
477
};
478
479
// Set up file source
480
let file_source = source_for_location(&PathBuf::from("./src"), &[])?;
481
let source_result = file_source.scan()?;
482
483
// Build programs
484
let source_hashes = SourceHashes::from_files(&source_result.files);
485
let programs = build_programs(&config, &source_hashes)?;
486
487
// Generate and write artifacts
488
for project_config in &config.projects {
489
let artifacts = generate_artifacts(project_config, &programs)?;
490
for artifact in artifacts {
491
project_config.artifact_writer.write_artifact(&artifact)?;
492
}
493
project_config.artifact_writer.finalize()?;
494
}
495
496
println!("Compilation completed successfully!");
497
Ok(())
498
}
499
```