Skip to content

Conversation

@asoorm
Copy link
Contributor

@asoorm asoorm commented Oct 24, 2025

This adds the ability to collect GraphQL operations (queries/mutations) and emit .proto files so we can auto-generate servers and clients (via gRPC/Buf Connect) to consume the graph.

  • Added compileOperationsToProto function to map GraphQL operations -> protobuf AST -> proto text.
  • Introduced a new CLI flag --with-operations that selects operations-based generation mode.
  • field-number management (via a lock/manager) to avoid collisions and ensure deterministic ordering.
  • fragment-denormalization support: named fragments and inline fragments are resolved
  • Query operations now optionally support an --idempotent-queries flag to mark queries as having no side-effects (mapped to option idempotency_level = NO_SIDE_EFFECTS; in the generated proto).

Backwards compatibility
Existing schema-type-based generation unchanged. New mode opt-in.

Summary by CodeRabbit

  • New Features

    • GraphQL operations can now be compiled directly to Protocol Buffers definitions
    • Added custom scalar mappings for flexible type conversions
    • Added multi-language proto options support (Java, C#, Ruby, PHP, Objective-C, Swift)
    • Added query idempotency metadata configuration
    • Added stable field numbering across operation recompilations
    • Added server streaming support for subscription operations
  • Tests

    • Added comprehensive test coverage for GraphQL-to-Protocol Buffers operations compilation

asoorm added 14 commits October 24, 2025 11:50
Maps GraphQL types to Protocol Buffer types with full type system support:
- Scalars: nullable → wrapper types, non-null → direct types
- Lists: mapped to repeated fields
- Complex types: objects, enums, input objects mapped by name
- Custom scalar mappings and configuration options
Manages field number assignment with collision avoidance.
Tracks numbers per-message, supports manual assignment and reset.
Builds request messages from operation variables with input object
and enum support. Handles variable type conversion and field numbering.
Converts protobuf AST to formatted proto text with proper syntax,
package declarations, imports, and indentation.
Wires together all modules to provide complete operation-to-proto
conversion. Adds input object processing and updates exports.
Import Kind from graphql and use Kind.SELECTION_SET instead of
'SelectionSet' string to fix type error in test.
…eration-to-proto

Add support for named fragments (fragment spreads) and inline fragments.
Fragments are expanded inline to produce self-contained proto messages with
deterministic field ordering, ensuring wire compatibility across router restarts.

- Collect fragment definitions from GraphQL documents
- Recursively resolve fragment spreads and inline fragments
- Handle interfaces, unions, and nested fragment compositions
- Prevent duplicate field additions
Adds a new queryNoSideEffects option to compileOperationsToProto that marks
Query operations with 'option idempotency_level = NO_SIDE_EFFECTS;' in the
generated proto definition. Mutations are not affected by this option.
**Title:**
Add operations-based proto generation mode to gRPC service command

**Body:**
Introduces a new `--with-operations` flag that enables generating protobuf schemas directly from GraphQL operation files (.graphql, .gql) instead of SDL types. This operations-based mode uses the `compileOperationsToProto` function and skips mapping.json generation since it's not needed for operation-based schemas. Also adds an `--idempotent-queries` flag to mark Query operations with NO_SIDE_EFFECTS idempotency level when using operations mode. The command now validates the operations directory, reads all GraphQL files from it, and provides clear feedback about which generation mode was used and which files were created.
@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the cli label Oct 24, 2025
@asoorm asoorm marked this pull request as ready for review October 25, 2025 05:09
@asoorm asoorm force-pushed the ahmet/eng-8163-operations-to-proto branch from cb28579 to e284194 Compare October 25, 2025 05:14
Add support for Java, Ruby, Swift, PHP, C#, and Objective-C language options
when generating Protocol Buffers from GraphQL schemas.

New options: --java-package, --java-outer-classname, --java-multiple-files,
--csharp-namespace, --ruby-package, --php-namespace, --php-metadata-namespace,
--objc-class-prefix, --swift-prefix

```
wgc grpc-service generate my-service -i schema.graphql \
  --java-package com.example.myservice \
  --java-outer-classname MyServiceProto \
  --java-multiple-files

wgc grpc-service generate my-service -i schema.graphql \
  --ruby-package MyService::Proto

wgc grpc-service generate my-service -i schema.graphql \
  --swift-prefix MS

wgc grpc-service generate my-service -i schema.graphql \
  --php-namespace "Example\\MyService" \
  --php-metadata-namespace "Example\\MyService\\Metadata"

wgc grpc-service generate my-service -i schema.graphql \
  --go-package github.com/example/myservice \
  --java-package com.example.myservice \
  --csharp-namespace Example.MyService \
  --ruby-package MyService::Proto \
  --swift-prefix MS
```
@asoorm asoorm force-pushed the ahmet/eng-8163-operations-to-proto branch from efd48b7 to 9ff4661 Compare October 25, 2025 15:08
@github-actions github-actions bot removed the router label Oct 25, 2025
@asoorm asoorm force-pushed the ahmet/eng-8163-operations-to-proto branch from 8368b3b to ba6a707 Compare October 25, 2025 16:37
Add GraphQL spec validation to operation compilation to catch invalid operations
including circular fragment references before proto generation. Implements two-layer
defense: GraphQL validation (primary) catches spec violations like circular fragments,
while depth limiting (default: 50, configurable via maxDepth) provides safety net
against stack overflow from deeply nested operations.

- Add validate() with specifiedRules to compileOperationsToProto()
- Add comprehensive validation tests (circular fragments, unused vars, etc.)
- Add inline snapshot test showing nested message structure from recursion
- Fix tests using invalid GraphQL (unused variables, circular fragments)

Addresses PR feedback about recursion stop conditions.
@asoorm asoorm force-pushed the ahmet/eng-8163-operations-to-proto branch 2 times, most recently from 7509622 to c2c2cdf Compare October 26, 2025 11:28
@asoorm asoorm force-pushed the ahmet/eng-8163-operations-to-proto branch from c2c2cdf to 8366a1c Compare October 26, 2025 11:30
Previously, nested GraphQL lists like [[String]] were flattened to
repeated string, losing structure. Now generates proper wrapper
messages matching SDL-to-proto behavior.

- Add nested list detection and wrapper message generation
- Extract shared list utilities to eliminate code duplication
@asoorm asoorm force-pushed the ahmet/eng-8163-operations-to-proto branch from c1fa72f to 51d2da7 Compare October 28, 2025 22:08
ability to prefix operation type to rpc method names and request and response messages.
Prefixes RPC method names with operation type (Query/Mutation) when generating proto from operations. Only applies with --with-operations.
Add --prefix-operation-type flag to prefix RPC method names with
operation type (Query/Mutation/Subscription).

Also fix proto generation issues:
- Allow unknown directives in GraphQL validation
- Fix nested message handling in proto merging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants