diff --git a/docs/cli/router/plugin.mdx b/docs/cli/router/grpc-plugin.mdx similarity index 100% rename from docs/cli/router/plugin.mdx rename to docs/cli/router/grpc-plugin.mdx diff --git a/docs/cli/router/plugin/build.mdx b/docs/cli/router/grpc-plugin/build.mdx similarity index 93% rename from docs/cli/router/plugin/build.mdx rename to docs/cli/router/grpc-plugin/build.mdx index 4ccbccb9..ce903109 100644 --- a/docs/cli/router/plugin/build.mdx +++ b/docs/cli/router/grpc-plugin/build.mdx @@ -4,14 +4,14 @@ description: 'Build a gRPC router plugin' icon: 'hammer' --- -# wgc router plugin build +# wgc router grpc-plugin build The `build` command generates gRPC code based on your GraphQL schema and compiles your plugin into platform-specific binaries. ## Usage ```bash -wgc router plugin build [options] [directory] +wgc router grpc-plugin build [options] [directory] ``` ## Arguments @@ -63,25 +63,25 @@ You can also install the dependencies manually and use an IDE with Go support. T ### Build for the current platform ```bash -wgc router plugin build ./my-plugin +wgc router grpc-plugin build ./my-plugin ``` ### Generate code only ```bash -wgc router plugin build --generate-only ./my-plugin +wgc router grpc-plugin build --generate-only ./my-plugin ``` ### Build for multiple platforms ```bash -wgc router plugin build --platform darwin-arm64 linux-amd64 ./my-plugin +wgc router grpc-plugin build --platform darwin-arm64 linux-amd64 ./my-plugin ``` ### Build for all supported platforms ```bash -wgc router plugin build --all-platforms ./my-plugin +wgc router grpc-plugin build --all-platforms ./my-plugin ``` ## Supported Platforms diff --git a/docs/cli/router/plugin/init.mdx b/docs/cli/router/grpc-plugin/init.mdx similarity index 95% rename from docs/cli/router/plugin/init.mdx rename to docs/cli/router/grpc-plugin/init.mdx index f8e92446..3710613a 100644 --- a/docs/cli/router/plugin/init.mdx +++ b/docs/cli/router/grpc-plugin/init.mdx @@ -4,14 +4,14 @@ description: 'Scaffold a new gRPC router plugin' icon: 'file-circle-plus' --- -# wgc router plugin init +# wgc router grpc-plugin init The `init` command scaffolds a new gRPC router plugin project with all the necessary files and directory structure. ## Usage ```bash -wgc router plugin init [options] +wgc router grpc-plugin init [options] ``` ## Arguments @@ -83,13 +83,13 @@ You can also generate only the plugin without bootstrapping a full router projec ### Basic usage ```bash -wgc router plugin init users +wgc router grpc-plugin init users ``` ### Specify a custom directory ```bash -wgc router plugin init users -d ./plugins +wgc router grpc-plugin init users -d ./plugins ``` ## Next Steps diff --git a/docs/cli/router/plugin/test.mdx b/docs/cli/router/grpc-plugin/test.mdx similarity index 96% rename from docs/cli/router/plugin/test.mdx rename to docs/cli/router/grpc-plugin/test.mdx index aac1ec32..5af453db 100644 --- a/docs/cli/router/plugin/test.mdx +++ b/docs/cli/router/grpc-plugin/test.mdx @@ -4,14 +4,14 @@ description: 'Run tests for a gRPC router plugin' icon: 'vial' --- -# wgc router plugin test +# wgc router grpc-plugin test The `test` command runs tests for your gRPC router plugin to verify its functionality. ## Usage ```bash -wgc router plugin test [options] [directory] +wgc router grpc-plugin test [options] [directory] ``` ## Arguments @@ -65,7 +65,7 @@ The default test file tests the plugin's ability to handle basic GraphQL queries ### Run tests for a plugin ```bash -wgc router plugin test ./my-plugin +wgc router grpc-plugin test ./my-plugin ``` ## Best Practices diff --git a/docs/cli/router/grpc-service.mdx b/docs/cli/router/grpc-service.mdx new file mode 100644 index 00000000..9924f9cf --- /dev/null +++ b/docs/cli/router/grpc-service.mdx @@ -0,0 +1,16 @@ +--- +title: "gRPC Service" +icon: network-wired +sidebarTitle: Overview +description: "Commands for working with gRPC services for the Cosmo Router" +--- + +WunderGraph Cosmo CLI includes commands for working with gRPC services for the Cosmo Router. + + + + Generate a protobuf definition and mapping file for a gRPC service from a GraphQL schema + + + +For detailed documentation about gRPC services and how they work, see the [Router gRPC Services](/router/grpc/grpc-services) documentation. \ No newline at end of file diff --git a/docs/cli/router/grpc-service/generate.mdx b/docs/cli/router/grpc-service/generate.mdx new file mode 100644 index 00000000..78b462dc --- /dev/null +++ b/docs/cli/router/grpc-service/generate.mdx @@ -0,0 +1,68 @@ +--- +title: "Generate" +icon: code +sidebarTitle: Generate +description: "Generate a protobuf definition for a gRPC service from a GraphQL schema" +--- + +# wgc router grpc-service generate + +The `generate` command generates a protobuf definition and mapping file for a gRPC service from a GraphQL schema, +which can be used to implement a gRPC service and can be used for the composition. + +## Usage + +```bash +wgc router grpc-service generate [options] [service-name] +``` + +## Arguments + +| Argument | Description | Default | +|----------|-------------|---------| +| `service-name` | Name of the gRPC service | `service.v1` | + +## Options + +| Option | Description | Default | +|--------|-------------|---------| +| `-i, --input ` | The GraphQL schema file to generate a protobuf schema from | Required | +| `-o, --output ` | The output directory for the protobuf schema | `.` | +| `-p, --package-name ` | The name of the proto package | `service.v1` | +| `-g, --go-package ` | Adds an `option go_package` to the proto file | None | + +## Description + +This command generates a protobuf definition for a gRPC service from a GraphQL schema. + +## Examples + +### Generate a protobuf definition for a gRPC service from a GraphQL schema + +```bash +wgc router grpc-service generate -i ./schema.graphql -o ./service MyService +``` + +### Define a custom package name + +```bash +wgc router grpc-service generate -i ./schema.graphql -o ./service MyService --package-name my.custom.package +``` + +### Define a custom go package name + +```bash +wgc router grpc-service generate -i ./schema.graphql -o ./service MyService --go-package github.com/wundergraph/cosmo/service/my-service +``` + +## Output + +The command generates multiple files in the output directory: + +- `service.proto`: The protobuf definition for the gRPC service +- `service.mapping.json`: The mapping file for the gRPC service +- `service.proto.lock.json`: The lock file for the protobuf definition + +The generated protobuf definition can be used to implement a gRPC service in any language that supports protobuf. + +The mapping and the protobuf definition is needed for the composition part. \ No newline at end of file diff --git a/docs/docs.json b/docs/docs.json index 5cdebb86..36c2aad9 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -49,7 +49,8 @@ "tutorial/using-persisted-operations", "tutorial/using-apollo-router-gateway-with-cosmo-oss-schema-registry", "tutorial/supergraph-previews-for-every-pull-request", - "tutorial/gradual-and-experimental-feature-rollout-with-feature-flags" + "tutorial/gradual-and-experimental-feature-rollout-with-feature-flags", + "tutorial/grpc-service-quickstart" ] } ] @@ -218,13 +219,21 @@ ] }, { - "group": "Plugin", + "group": "gRPC Plugin", "icon": "plug", "pages": [ - "cli/router/plugin", - "cli/router/plugin/init", - "cli/router/plugin/build", - "cli/router/plugin/test" + "cli/router/grpc-plugin", + "cli/router/grpc-plugin/init", + "cli/router/grpc-plugin/build", + "cli/router/grpc-plugin/test" + ] + }, + { + "group": "gRPC Service", + "icon": "network-wired", + "pages": [ + "cli/router/grpc-service", + "cli/router/grpc-service/generate" ] } ] @@ -398,9 +407,14 @@ "router/mcp", "router/custom-modules", { - "group": "Plugins", - "icon": "plug", - "pages": ["router/plugins", "router/plugins/debugging"] + "group": "gRPC", + "icon": "network-wired", + "pages": [ + "router/gRPC/concepts", + "router/gRPC/grpc-services", + "router/gRPC/grpc-plugins", + "router/gRPC/debugging" + ] }, "router/authentication-and-authorization", "router/advanced-data-privacy", diff --git a/docs/router/gRPC/concepts.mdx b/docs/router/gRPC/concepts.mdx new file mode 100644 index 00000000..1945dc45 --- /dev/null +++ b/docs/router/gRPC/concepts.mdx @@ -0,0 +1,221 @@ +--- +title: "Concepts" +icon: "lightbulb" +sidebarTitle: Concepts +description: 'Core concepts for gRPC integration in Cosmo Router' +--- + +## Introduction + +The Cosmo Router supports integration with gRPC through a schema-first approach. You define a GraphQL schema that represents the interface to your gRPC implementation, and the Cosmo tooling generates the corresponding Protocol Buffer definitions and mappings that enable the router to establish communication. + +This approach allows you to bridge any service - whether it's gRPC, REST, SOAP, or legacy systems - into your GraphQL Federation Supergraph by creating a protocol translation layer. The router handles the communication with your implementations based on the generated mappings, making it easy to modernize your architecture while preserving existing investments. + + +## What is gRPC? + +gRPC is a modern, open-source, high-performance RPC framework that enables communication between services using a lightweight binary protocol. It provides a robust foundation for building distributed systems and is widely adopted in the industry. + +Key characteristics include: +* **Language and platform agnostic** - allows you to define service interfaces in a language-neutral way +* **Protocol Buffers** - uses protobuf as the interface definition language for type-safe communication +* **High performance** - binary protocol enables efficient data serialization and transmission +* **Industry standard** - widely adopted across microservices architectures + +You can find more information about gRPC [here](https://grpc.io/docs/what-is-grpc/introduction/). + +## What is gRPC Integration in Cosmo? + +gRPC integration in Cosmo allows you to incorporate gRPC-based functionality into your GraphQL Federation through a code generation workflow: + +- **Schema-driven integration** where you define GraphQL schemas that represent your gRPC interfaces +- **Automatic protobuf generation** from your GraphQL schema definitions +- **Router-managed communication** where the Cosmo Router handles gRPC communication +- **Protocol translation** between GraphQL requests and gRPC calls +- **Type-safe mappings** ensuring consistency between GraphQL and protobuf definitions +- **Flexible deployment models** supporting both local and remote gRPC implementations + +## Core Workflow + + + + Create a GraphQL schema that represents the interface to your gRPC implementation. This schema defines the types, queries, mutations, and inputs that will be exposed through your GraphQL API. + + + Use the Cosmo CLI to automatically generate protobuf service definitions and mapping configurations from your GraphQL schema. This creates the bridge between GraphQL and gRPC protocols. + + + Build your gRPC implementation using the generated protobuf definitions. This implements the business logic for your GraphQL operations. + + + Configure the Cosmo Router to understand how to communicate with your gRPC implementation. + + + Deploy your setup and test the integration by making GraphQL queries that are translated to gRPC calls. + + + +## Motivation + +Many companies see the value of GraphQL Federation but are hesitant to adopt it because they have existing systems that are incompatible, like legacy systems, REST APIs, SOAP, etc. + +gRPC integration solves this problem by making it easy to generate adapters between your Supergraph and existing systems. The system is designed with modern development tools in mind - define a GraphQL schema, provide an OpenAPI document, a SOAP WSDL, or even just some curl commands, and AI coding assistants can generate adapter code and tests in minutes. + +Thanks to the strongly-typed proto definition and built-in tooling, development becomes faster and more reliable. + +## Core Benefits + + + + While everyone understands the value of "one schema, one query," building and maintaining production-grade subgraphs across diverse environments remains challenging. Spec support, runtime performance, and type safety depend on your implementation quality. + + + + Our approach combines GraphQL's schema-first flexibility with gRPC's performance and type safety. You can develop implementations in any language that supports gRPC while maintaining GraphQL's benefits. + + + + The strict typing and automatic code generation from Protocol Buffers (proto) definitions provides an immense productivity boost, especially in the era of generative AI. The generated proto-based gRPC code creates a strongly-typed foundation that AI tools can effectively understand and extend. + + + + With gRPC integration, there's no way to get around the proto definition. If the implementation compiles against the proto definition, you know it's correct. This eliminates a whole class of integration issues. + + + + gRPC implementations are 100% compatible with existing Apollo Federation Subgraph implementations. You can use gRPC alongside existing subgraphs seamlessly. + + + + gRPC implementations leverage Cosmo Router's DataLoader capabilities which batch requests by default, avoiding common performance pitfalls. + + + + When new features are added to the GraphQL Federation specification, gRPC implementations can immediately take advantage of them since federation logic is handled within the Router. + + + gRPC integration is a great fit for LLM-based applications. From a generated proto definition, an LLM can generate a gRPC service implementation in any supported language. + + + +## Benefits Over Traditional REST Integration + +When compared to integrating REST APIs into GraphQL Federation, gRPC offers several advantages: + + + + Binary protocol and HTTP/2 multiplexing provide better performance than traditional REST over HTTP/1.1, especially for high-frequency communication. + + + Generate protobuf definitions and mappings directly from your GraphQL schema, reducing development time and ensuring consistency. + + + Native support for streaming data enables real-time capabilities and efficient handling of large datasets. + + + GraphQL schemas serve as the single source of truth for service contracts, with protobuf definitions generated automatically to ensure compatibility. + + + + + Streaming support is currently not yet supported for gRPC services in the router. + + +## Architecture Overview + +gRPC integration into GraphQL Federation follows this pattern: + +1. **Schema Definition**: You define GraphQL schemas that represent your gRPC interfaces +2. **Code Generation**: Cosmo tooling generates protobuf definitions and mappings from your GraphQL schemas +3. **Router Configuration**: The router is configured with the generated mappings to understand how to communicate with your gRPC implementations +4. **Request Processing**: When GraphQL queries are received, the router translates relevant portions into gRPC calls +5. **Protocol Translation**: The router handles the translation between GraphQL and gRPC protocols +6. **Response Assembly**: Results from gRPC calls are translated back to GraphQL and assembled into the final response + +## Implementation Options + +Cosmo provides two main approaches for gRPC integration: + +### gRPC Plugins +- **Local execution**: Run as separate processes managed by the router +- **Simplified deployment**: Deployed alongside the router +- **Lower latency**: Direct inter-process communication +- **Currently Go-only**: Implementation language is limited to Go + +### gRPC Services +- **Remote execution**: Run as independent services anywhere in your infrastructure +- **Language flexibility**: Implement in any language that supports gRPC +- **Independent scaling**: Scale services based on their specific requirements +- **Distributed architecture**: Services can be deployed across different environments + + +## Choosing Between gRPC Services and Plugins + +When implementing gRPC integration in your GraphQL Federation, you have two main options: **gRPC Services** and **gRPC Plugins**. Each approach has distinct advantages that make them suitable for different scenarios. + +### When to Choose gRPC Services + + + + Implement services in any language that supports gRPC - Python, Java, C#, Node.js, Rust, and many others. + + + Different teams can own and operate their services independently with their preferred technologies. + + + Scale services based on their specific load patterns and resource requirements. + + + Deploy services across different environments, datacenters, or cloud regions. + + + Maintain existing microservices architecture and deployment practices. + + + Services can have different release schedules and deployment pipelines. + + + +### When to Choose gRPC Plugins + + + + Deploy plugins alongside the router with minimal infrastructure complexity. + + + Achieve lower latency through direct inter-process communication. + + + Leverage Go's performance and ecosystem for plugin development. + + + Manage deployment, monitoring, and lifecycle in a unified manner. + + + +### Decision Matrix + +| Factor | gRPC Services | gRPC Plugins | +|--------|---------------|--------------| +| **Language Support** | Any gRPC language | Go only (More coming soon) | +| **Deployment Model** | Distributed microservices | Co-located with router | +| **Team Autonomy** | High - independent ownership | Low - router-dependent | +| **Performance** | Network latency overhead | Minimal latency | +| **Scaling** | Independent per service | Coupled to router | +| **Operational Complexity** | Higher - distributed ops | Lower - unified ops | + + +## Roadmap + +We're actively working on addressing these limitations. Future releases will include: +- Enhanced Federation feature support +- Subscription support for real-time data +- Deep integration with the cosmo observability stack + +For the most up-to-date information, check our [GitHub repository](https://github.com/wundergraph/cosmo). + +## Next Steps + +- [gRPC Services](/router/gRPC/grpc-services) - Learn about gRPC services +- [gRPC Plugins](/router/gRPC/grpc-plugins) - Learn about gRPC plugins +- [gRPC Tutorial](/tutorial/grpc-service-quickstart) - Get started with your first gRPC service \ No newline at end of file diff --git a/docs/router/plugins/debugging.mdx b/docs/router/gRPC/debugging.mdx similarity index 99% rename from docs/router/plugins/debugging.mdx rename to docs/router/gRPC/debugging.mdx index 990128b8..5681d6a3 100644 --- a/docs/router/plugins/debugging.mdx +++ b/docs/router/gRPC/debugging.mdx @@ -1,11 +1,10 @@ --- title: 'Debugging' description: 'Debug router plugins using various IDEs and tools' +sidebarTitle: Debugging icon: 'bug' --- -# Debugging Plugins - When developing router plugins, you might need to debug your code to understand its behavior or fix issues. This guide explains how to build plugins in debug mode and attach debuggers using different tools. ## Design Philosophy diff --git a/docs/router/plugins.mdx b/docs/router/gRPC/grpc-plugins.mdx similarity index 89% rename from docs/router/plugins.mdx rename to docs/router/gRPC/grpc-plugins.mdx index 1227f2e8..fb50d1d3 100644 --- a/docs/router/plugins.mdx +++ b/docs/router/gRPC/grpc-plugins.mdx @@ -1,24 +1,23 @@ --- title: 'gRPC Plugins' -description: 'Bridge any service into your GraphQL Federation Supergraph with secure, performant gRPC plugins simplifying architecture while enabling type-safe integration of REST, databases, and legacy systems' +description: 'Local gRPC plugins for high-performance GraphQL Federation with simplified deployment' +sidebarTitle: gRPC Plugins icon: "plug" --- ## Introduction -The Cosmo Router supports extending the GraphQL Federation Supergraph with gRPC plugins. -This allows you to extend your Schema with non-GraphQL services like REST or SOAP APIs, -gRPC services, databases, and legacy systems. - -The Cosmo cli ([wgc](/cli)) generates a strongly-typed proto definition for your plugin. -Together with the built-in testing framework, -gRPC plugins are purpose-built to leverage LLMs to generate adapter code between your GraphQL Schema and the underlying data source. +gRPC plugins are extensions that run as separate processes locally alongside the Cosmo Router and communicate over Google's Remote Procedure Call ([gRPC](https://grpc.io/)) protocol. Unlike gRPC services that run remotely over the network, plugins provide the simplest deployment model with the highest performance for GraphQL Federation. +The Cosmo cli ([wgc](/cli)) provides you with a set of tools to create and build gRPC plugins. +Together with the built-in testing framework, gRPC plugins are purpose-built to leverage LLMs to generate adapter code between your GraphQL Schema and the underlying data source. In addition, the Cosmo Router manages the lifecycle of plugins, including hot-reloading plugins without any service interruption. There's no need to deploy "Subgraph" services just to bring an existing API into your Supergraph. -The workflow is simple: +For an overview of gRPC concepts shared between plugins and services, see our [gRPC Concepts documentation](/router/grpc/concepts). + +## Workflow @@ -28,14 +27,18 @@ The workflow is simple: Use wgc to generate a proto definition for your plugin - Implement the plugin in any language that supports gRPC + Implement the plugin in Go using the generated interfaces - Hook up the plugin to your Router + Hook up the plugin to your Router configuration -gRPC plugins are currently in beta. The API may change in future releases. +gRPC plugins are currently in beta. The API may change in future releases. + +## What Makes gRPC Plugins Unique + +gRPC plugins are local extensions that run as separate processes managed by the Cosmo Router. These plugins: ## Demo and Example @@ -216,9 +219,9 @@ Every plugin comes with a `Makefile` that provides a set of commands to build, t ### Plugin Directory Structure -When you initialize a plugin using `wgc router plugin init`, it creates a complete router project with a hello world plugin. +When you initialize a plugin using `wgc router grpc-plugin init`, it creates a complete router project with a hello world plugin. -For more details on the directory structure and build process, see the [`wgc router plugin init`](/cli/router/plugin/init) documentation. +For more details on the directory structure and build process, see the [`wgc router grpc-plugin init`](/cli/router/grpc-plugin/init) documentation. ## Debugging Plugins @@ -266,7 +269,6 @@ WORKDIR /app We're actively working on enhancing plugin deployment with: -- **Remote gRPC Plugins**: Support for plugins running as separate services, enabling independent scaling and deployment - **Cosmo Cloud Plugin Registry**: Native integration with Cosmo Cloud allowing you to push plugins directly to the platform without the need to re-deploy the Router These capabilities will further simplify the management and deployment of plugins in production environments. diff --git a/docs/router/gRPC/grpc-services.mdx b/docs/router/gRPC/grpc-services.mdx new file mode 100644 index 00000000..833cb6ee --- /dev/null +++ b/docs/router/gRPC/grpc-services.mdx @@ -0,0 +1,107 @@ +--- +title: "gRPC Services" +description: "Deploy gRPC services independently for distributed GraphQL Federation." +sidebarTitle: gRPC Services +icon: server +--- + +## Introduction + +gRPC services in Cosmo are independent, remotely deployed services that communicate with the Cosmo Router over the network using gRPC protocol. Unlike gRPC plugins that run as local processes managed by the router, gRPC services operate as standalone microservices that can be deployed anywhere in your infrastructure. + +This approach is ideal for distributed architectures where services are owned by different teams, require independent scaling, or need to be implemented in languages other than Go. + +For an overview of gRPC concepts shared between plugins and services, see our [gRPC Concepts documentation](/router/grpc/concepts). + +## What Makes gRPC Services Unique + +gRPC services are standalone microservices that expose their functionality through gRPC endpoints and integrate into your GraphQL Federation as subgraphs. These services: + +- **Run independently** as separate deployments with their own lifecycle management +- **Communicate over the network** using standard gRPC protocol +- **Maintain service autonomy** while participating in the federated graph +- **Scale independently** based on their specific requirements +- **Support any gRPC language** - Python, Java, C#, Node.js, Rust, and many others + +The key distinction from gRPC plugins is that services are: +- **Remotely deployed** rather than co-located with the router +- **Network-based** communication instead of inter-process communication +- **Independently managed** with separate deployment pipelines +- **Service-oriented** following microservices architecture patterns + +## Key Differences from gRPC Plugins + + + + Unlike plugins that run as locally forked processes managed by the router, gRPC services can be deployed anywhere in your infrastructure - different servers, containers, or even cloud regions. + + + + While gRPC plugins currently only support Go, gRPC services can be implemented in any language that supports gRPC - Python, Java, C#, Node.js, Rust, and many others. + + + + Services can be scaled independently based on their specific load patterns and resource requirements, without affecting the router or other services. + + + + Communication happens over the network using standard gRPC protocols, enabling distributed architectures and cross-datacenter deployments. + + + + Each service maintains its own deployment lifecycle, monitoring, and operational concerns, following traditional microservices patterns. + + + + Different teams can own and operate their services independently, using their preferred languages, frameworks, and deployment strategies. + + + +## When to Choose gRPC Services + +**Choose gRPC Services when:** +- You need to use languages other than Go +- Services are owned by different teams +- You require independent scaling and deployment +- Services are distributed across different environments +- You want to maintain existing microservices architecture +- Services have different release cycles + +**Choose gRPC Plugins when:** +- You want the simplest possible deployment model +- Performance is critical (lower latency with local communication) +- You're comfortable with Go development +- You prefer unified deployment and monitoring + +## Service Architecture + +gRPC services integrate into GraphQL Federation through this architecture: + +1. **Independent Deployment**: Services are deployed and managed independently from the router +2. **Network Discovery**: The router discovers and connects to services over the network +3. **Protocol Translation**: The router translates GraphQL requests to gRPC calls over the network +4. **Autonomous Operation**: Services handle their own scaling, monitoring, and lifecycle management +5. **Distributed Response**: Results are collected from multiple distributed services and assembled + +## Deployment Considerations + +### Network Configuration +- Services must be accessible from the router over the network +- Consider network latency and reliability in your architecture +- Plan for service discovery and health checking + +### Security +- Implement proper authentication between router and services +- Consider network security and encryption (when TLS support is available) +- Follow microservices security best practices + +### Monitoring and Observability +- Set up independent monitoring for each service +- Implement distributed tracing across services +- Plan for service health checks and circuit breakers + +### Scaling Strategy +- Design services to scale independently based on load +- Consider auto-scaling policies for each service +- Plan for different resource requirements per service + diff --git a/docs/tutorial/grpc-service-quickstart.mdx b/docs/tutorial/grpc-service-quickstart.mdx new file mode 100644 index 00000000..e085d7c6 --- /dev/null +++ b/docs/tutorial/grpc-service-quickstart.mdx @@ -0,0 +1,401 @@ +--- +title: "Federate gRPC into Your Supergraph" +description: "This guide will walk you through the process of integrating a gRPC service into your router. We will use a simple GraphQL schema to define the interface of our gRPC service." +sidebarTitle: Federate gRPC into Your Supergraph +icon: server +--- + +## Prerequisites + +- [Cosmo CLI](https://github.com/wundergraph/cosmo/releases/tag/wgc%400.82.0) // TODO add proper version. +- [Cosmo Router](https://github.com/wundergraph/cosmo/releases/tag/router%400.222.1) // TOOD add router version. + +### Step 1: Create a GraphQL Schema + +First, define a GraphQL schema that represents your gRPC service interface: + +```graphql +type Query { + getProject(id: ID!): Project + listProjects: [Project!]! +} + +type Mutation { + createProject(input: CreateProjectInput!): Project! + updateProject(id: ID!, input: UpdateProjectInput!): Project! +} + +type Project { + id: ID! + name: String! + description: String + status: ProjectStatus! + createdAt: String! + updatedAt: String! +} + +input CreateProjectInput { + name: String! + description: String +} + +input UpdateProjectInput { + name: String + description: String + status: ProjectStatus +} + +enum ProjectStatus { + ACTIVE + INACTIVE + ARCHIVED +} +``` + +### Step 2: Generate Protobuf Files + +Use the Cosmo CLI to generate the protobuf definitions and mappings from your GraphQL schema: + +```bash +wgc router grpc-service \ + generate \ + -p playground \ + -i ./schema.graphql \ + Projects +``` + +This command will create: +- `service.proto` - The protobuf service definition +- `mapping.json` - The mapping configuration between GraphQL and gRPC +- `service.proto.lock.json` - The lock file for the protobuf definitions + + +Your protobuf file will look like this: + +```proto +syntax = "proto3"; +package playground; + +// Service definition for ProjectsService +service ProjectsService { + rpc MutationCreateProject(MutationCreateProjectRequest) returns (MutationCreateProjectResponse) {} + rpc MutationUpdateProject(MutationUpdateProjectRequest) returns (MutationUpdateProjectResponse) {} + rpc QueryGetProject(QueryGetProjectRequest) returns (QueryGetProjectResponse) {} + rpc QueryListProjects(QueryListProjectsRequest) returns (QueryListProjectsResponse) {} +} + +// Request message for getProject operation. +message QueryGetProjectRequest { + string id = 1; +} +// Response message for getProject operation. +message QueryGetProjectResponse { + Project get_project = 1; +} +// Request message for listProjects operation. +message QueryListProjectsRequest { +} +// Response message for listProjects operation. +message QueryListProjectsResponse { + repeated Project list_projects = 1; +} +// Request message for createProject operation. +message MutationCreateProjectRequest { + CreateProjectInput input = 1; +} +// Response message for createProject operation. +message MutationCreateProjectResponse { + Project create_project = 1; +} +// Request message for updateProject operation. +message MutationUpdateProjectRequest { + string id = 1; + UpdateProjectInput input = 2; +} +// Response message for updateProject operation. +message MutationUpdateProjectResponse { + Project update_project = 1; +} + +message Project { + string id = 1; + string name = 2; + string description = 3; + ProjectStatus status = 4; + string created_at = 5; + string updated_at = 6; +} + +message CreateProjectInput { + string name = 1; + string description = 2; +} + +message UpdateProjectInput { + string name = 1; + string description = 2; + ProjectStatus status = 3; +} + +enum ProjectStatus { + PROJECT_STATUS_UNSPECIFIED = 0; + PROJECT_STATUS_ACTIVE = 1; + PROJECT_STATUS_INACTIVE = 2; + PROJECT_STATUS_ARCHIVED = 3; +} +``` + +Depending on the language you are using, you might need to adjust the options. The package name needs to be the same as the one you used in the `wgc router grpc-service generate` command. + +### Step 3: Create a Compose Configuration + +Create a `compose.yaml` file to configure your gRPC service integration: +Make sure to use a valid gRPC URL for the client to connect to. See [gRPC URL Format](https://github.com/grpc/grpc/blob/master/doc/naming.md) for more information. + +```yaml +version: 1 +subgraphs: + - name: projects + routing_url: dns:///localhost:4011 + grpc: + schema_file: ./schema.graphql + proto_file: ./generated/service.proto + mapping_file: ./generated/mapping.json +``` + +### Step 4: Generate Router Configuration + +Use the compose file to generate the router configuration: + +```bash +wgc router compose -i ./compose.yaml -o ./router.json +``` + +This creates a `config.json` file that the Cosmo Router will use to understand how to communicate with your gRPC service. + +### Step 5: Implement Your gRPC Service + +Now implement your gRPC service in your preferred language. + + + +```go main.go +package main + +import ( + "context" + "log" + "net" + "playground/service/service" + + "google.golang.org/grpc" +) + +func main() { + s := grpc.NewServer() + service.RegisterProjectsServiceServer(s, &ProjectsServiceServer{}) + + lis, err := net.Listen("tcp", ":50051") + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} + +var _ service.ProjectsServiceServer = (*ProjectsServiceServer)(nil) + +type ProjectsServiceServer struct { + service.UnimplementedProjectsServiceServer +} + +// MutationCreateProject implements service.ProjectsServiceServer. +func (p *ProjectsServiceServer) MutationCreateProject(context.Context, *service.MutationCreateProjectRequest) (*service.MutationCreateProjectResponse, error) { + // Your implementation here + return &service.MutationCreateProjectResponse{ + CreateProject: &service.Project{ + Id: "1", + Name: "Project 1", + }, + }, nil +} + +// MutationUpdateProject implements service.ProjectsServiceServer. +func (p *ProjectsServiceServer) MutationUpdateProject(context.Context, *service.MutationUpdateProjectRequest) (*service.MutationUpdateProjectResponse, error) { + // Your implementation here + return &service.MutationUpdateProjectResponse{ + UpdateProject: &service.Project{ + Id: "1", + Name: "Project 1", + }, + }, nil +} + +// QueryGetProject implements service.ProjectsServiceServer. +func (p *ProjectsServiceServer) QueryGetProject(context.Context, *service.QueryGetProjectRequest) (*service.QueryGetProjectResponse, error) { + // Your implementation here + return &service.QueryGetProjectResponse{ + GetProject: &service.Project{ + Id: "1", + Name: "Project 1", + }, + }, nil +} + +// QueryListProjects implements service.ProjectsServiceServer. +func (p *ProjectsServiceServer) QueryListProjects(context.Context, *service.QueryListProjectsRequest) (*service.QueryListProjectsResponse, error) { + // Your implementation here + return &service.QueryListProjectsResponse{ + ListProjects: []*service.Project{ + { + Id: "1", + Name: "Project 1", + }, + }, + }, nil +} +``` + + + + Create two files: `connect.ts` and `index.ts`. + + + ```ts connect.ts + import type { ConnectRouter } from "@connectrpc/connect"; + import { ProjectsService, ProjectStatus, Project } from "../gen/service_pb"; + + export default (router: ConnectRouter) => { + router.service(ProjectsService, { + queryGetProject: async (req) => { + // Your implementation here + return { + getProject: { + id: "1", + name: "Project 1" + } + } + }, + queryListProjects: async () => { + // Your implementation here + return { + listProjects: [ + { + id: "1", + name: "Project 1" + } + ] + }; + }, + mutationCreateProject: async (req) => { + // Your implementation here + return { + createProject: { + id: "1", + name: "Project 1" + } + } + }, + mutationUpdateProject: async (req) => { + // Your implementation here + return { + updateProject: { + id: "1", + name: "Project 1" + } + } + } + }); + ``` + + ```ts index.ts + import { fastify } from "fastify"; + import { fastifyConnectPlugin } from "@connectrpc/connect-fastify"; + import routes from "./connect"; + + async function main() { + const server = fastify({ + http2: true, + }); + + await server.register(fastifyConnectPlugin, { + routes, + grpc: true + }); + server.get("/", (_, reply) => { + reply.header("Content-Type", "text/plain"); + reply.code(200).send("Hello World!"); + }); + await server.listen({ host: "localhost", port: 4011 }); + console.log("server is listening at", server.addresses()); + } + + // You can remove the main() wrapper if you set type: module in your package.json, + // and update your tsconfig.json with target: es2017 and module: es2022. + void main(); + ``` + + + + + +### Step 6: Run the Router + +Create a `config.yaml` file in the same directory as your router binary. + + + ```yaml config.yaml + dev_mode: true + execution_config: + file: + # Path to the previous generated file + path: "router.json" # or EXECUTION_CONFIG_FILE_PATH + watch: true # EXECUTION_CONFIG_FILE_WATCH + graph: + # Result of `wgc router token create`. Can be omitted for local testing. + token: "" # GRAPH_API_TOKEN + ``` + + +Finally, run the router + +```bash +./router +``` + +### Step 7: Test Your Integration + +You can now go to [`localhost:3002`](http://localhost:3002) . You will see a playground and you're ready to test your changes. + +```graphql +query { + listProjects { + id + name + description + status + createdAt + } +} + +query { + getProject(id: "1") { + id + name + description + status + } +} +``` + +That's it! Your gRPC service is now integrated into your router and can be queried alongside other subgraphs in your supergraph. + +## Further Information + +- [gRPC Service Concepts](/router/gRPC/concepts) +- [gRPC Plugins](/router/gRPC/grpc-plugins) +- [gRPC Service Federation](/router/gRPC/grpc-services) + +