This tutorial demonstrates a Cosmo Connect workflow: federating a gRPC Service into your supergraph without needing to build a GraphQL server.

Prerequisites

Overview

This tutorial shows you how to create a gRPC subgraph from scratch using the Cosmo CLI templates. You’ll start with a project template that includes all the necessary files and code generation to get up and running quickly. The tutorial supports both TypeScript and Go implementations using Connect RPC, which is a modern gRPC framework with a great developer experience and performance.

Step 1: Initialize a gRPC Service Template

First, list the available gRPC templates:
wgc grpc-service list-templates
This will show you the available templates:
  • golang-connect-rpc - Go implementation using Connect RPC
  • typescript-connect-rpc-fastify - TypeScript implementation using Connect RPC and Fastify
Initialize your preferred template:
wgc grpc-service init --template typescript-connect-rpc-fastify --directory ./my-grpc-service
cd my-grpc-service

Step 2: Define Your GraphQL Schema

The template includes a simple “hello” schema. Let’s replace it with a more comprehensive project management schema. Edit the schema file:
Edit src/graph/schema.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 3: Generate Code and Configuration

The template includes build scripts that handle all code generation:
# Install dependencies and bootstrap the project
npm install
npm run bootstrap
This runs:
  • npm run generate:proto - Generates protobuf files from GraphQL schema
  • npm run generate:buf - Generates Connect RPC TypeScript code
  • npm run generate:router - Generates router execution config
  • npm run router:download - Downloads the Cosmo Router binary

Step 4: Implement Your Service Logic

Now implement the business logic for your gRPC service:
Edit src/routes.ts:
import type { ConnectRouter } from "@connectrpc/connect";
import { Service } from "./proto/service/v1/service_pb.js";

export default (router: ConnectRouter) => {
  router.service(Service, {
    queryGetProject: async (req) => {
      return {
        getProject: {
          id: req.id,
          name: "Sample Project",
          description: "A sample project",
          status: "ACTIVE",
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
        },
      };
    },
    
    queryListProjects: async () => {
      return {
        listProjects: [
          {
            id: "1",
            name: "Project One",
            description: "First project",
            status: "ACTIVE",
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          },
          {
            id: "2", 
            name: "Project Two",
            description: "Second project",
            status: "INACTIVE",
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          },
        ],
      };
    },
    
    mutationCreateProject: async (req) => {
      return {
        createProject: {
          id: Math.random().toString(36).substr(2, 9),
          name: req.input?.name || "",
          description: req.input?.description || "",
          status: "ACTIVE",
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
        },
      };
    },
    
    mutationUpdateProject: async (req) => {
      return {
        updateProject: {
          id: req.id,
          name: req.input?.name || "Updated Project",
          description: req.input?.description || "",
          status: req.input?.status || "ACTIVE",
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
        },
      };
    },
  });
};

Step 5: Run Your gRPC Service and Router

Start both the gRPC service and the Cosmo Router:
# Start both service and router
npm run start
This runs both services concurrently:
  • gRPC service on port 50051
  • Cosmo Router on port 3002

Step 6: Test Your Integration

Open your browser to http://localhost:3002 to access the GraphQL Playground. Try these queries:
query ListProjects {
  listProjects {
    id
    name
    description
    status
    createdAt
    updatedAt
  }
}

query GetProject {
  getProject(id: "1") {
    id
    name
    description
    status
    createdAt
    updatedAt
  }
}

mutation CreateProject {
  createProject(input: {
    name: "New Project"
    description: "A new project"
  }) {
    id
    name
    description
    status
    createdAt
    updatedAt
  }
}

Understanding the Generated Files

The template creates several important files:
  • src/graph/schema.graphql - Your GraphQL schema (source of truth)
  • src/proto/service/v1/ - Generated protobuf files
  • router.compose.yaml - Router composition configuration
  • router.config.yaml - Router runtime configuration
  • router.execution.config.json - Generated router execution config
  • package.json - Build scripts and dependencies

Further Information