DEV Community

Cover image for Extending Your GraphQL Router with TypeScript
Stefan  πŸš€
Stefan πŸš€

Posted on

Extending Your GraphQL Router with TypeScript

Cosmo Connect now supports TypeScript plugins. If you're already working in a TypeScript codebase, you can extend your GraphQL router without introducing Go or deploying additional services.

Why This Matters

Until now, router plugins required Go. That works fine for teams already using it, but creates friction for everyone else. Since most teams already write TypeScript, adding native support removes that barrier.

The typical use case: you need to expose some internal logic or wrap a legacy REST API without spinning up another service. Write a TypeScript plugin, define your GraphQL type, call your API, and transform the response. It functions like a subgraph but lives inside the router.

The Technical Setup

Cosmo Connect generates protobuf definitions from your GraphQL schema. When you write a plugin, you define the schema, generate the protos, implement handlers, and publish. The router handles the rest.

Scaffold a new plugin:

bash

wgc router plugin init planets --language ts

Enter fullscreen mode Exit fullscreen mode

Generate protobuf definitions:

bash

wgc router plugin generate --plugin-dir ./planets

Enter fullscreen mode Exit fullscreen mode

Your schema might look like:

graphql

type Query {
  planet: Planet!
}

type Planet {
  name: String!
  mass: Float!
}

Enter fullscreen mode Exit fullscreen mode

Every schema change requires regenerating protos so your plugin code has access to new fields.

Implementation

Handler logic goes in src/plugin-server.ts. Here's a simple example:

typescript

public async QueryPlanet(
  call: ServerUnaryCall<QueryPlanetRequest, QueryPlanetResponse>,
  callback: sendUnaryData<QueryPlanetResponse>
): Promise<void> {
  const response = new QueryPlanetResponse();
  const planet = new Planet();
  planet.setName("Earth");
  planet.setMass(5.972e24);
  response.setPlanet(planet);
  callback(null, response);
}

Enter fullscreen mode Exit fullscreen mode

In production, replace this with calls to your internal services, databases, or legacy systems.

Build and publish:

bash

wgc router plugin build --plugin-dir ./planets
wgc router plugin publish planets --namespace <namespace>
wgc subgraph update planets --namespace <namespace>

Enter fullscreen mode Exit fullscreen mode

The router reloads automatically, and your new field appears in the schema.

Schema Validation

Published plugins go through standard composition rules. No special checks for TypeScript. Test in the Playground like any other field.

Go vs TypeScript

Go plugins shipped first because the router is written in Go and uses HashiCorp's go-plugin library - most mechanics are handled out of the box. TypeScript required building more integration ourselves, which took longer.

If you want deeper context on our plugin architecture decisions, Jens wrote about it in REST in Peaceβ€”Connectors Were Never the Right Supergraph Abstraction.

Getting Started

Best way to learn: wrap a single REST endpoint. Define the type, implement the handler, publish, and query. You'll understand the full workflow in a real environment.

Complete walkthrough in our plugin tutorial.


Adapted from the original article on the WunderGraph blog.

Top comments (0)