Skip to content

bufbuild/knit-ts

Repository files navigation

🧶 Knit

License NPM Version NPM Version Slack

Knit brings GraphQL-like capabilities to RPCs. Knit has type-safe and declarative queries that shape the response, batching support to eliminate the N+1 problem, and first-class support for error handling with partial responses. It is built on top of Protobuf and Connect.

Knit is currently in alpha (α), and looking for feedback. Learn more about it at the Knit repo, and learn how to use it with the Tutorial.


This repo houses TypeScript packages for Knit:

Quick example

To demonstrate the querying capabilities of Knit we've made a Protobuf equivalent of the star wars API at swapi.dev. The definitions are available here.

Run the following command to install the runtime package and schema for the star wars APIs:

npm i @bufbuild/knit @buf/bufbuild_knit-demo.bufbuild_knit-es

In a TypeScript file write the following query:

import { createClient } from "@bufbuild/knit";
import type { FilmsService } from "@buf/bufbuild_knit-demo.bufbuild_knit-es/buf/knit/demo/swapi/film/v1/film_knit";
import type {} from "@buf/bufbuild_knit-demo.bufbuild_knit-es/buf/knit/demo/swapi/relations/v1/relations_knit";

const client = createClient<FilmsService>({
  baseUrl: "https://knit-demo.connect.build", // The gateway-url
});

// Construct a query.
//
// The type system will ensure a query is valid.
const filmsResult = await client.fetch({
  // The fully qualified service name of the RPC you want to invoke.
  "buf.knit.demo.swapi.film.v1.FilmService": {
    // The camelCase name of the RPC you want to invoke.
    getFilms: {
      // $ is the request message for the RPC.
      $: { ids: ["1"] },
      // The fields you want to select from the result.
      films: {
        id: {},
        title: {},
        director: {},
        releaseDate: {},
        // Include the relation you want to use.
        // This field is not part of the original
        // proto definition of a `Film`, it comes
        // from `.../relations_knit`.
        characters: {
          // Relations can accept additional parameters.
          // In this case it accepts a limit parameter
          // to limit the number of characters returned.
          $: { limit: 10 }
          // The fields you want to select from the characters.
          id: {},
          name: {},
        },
      },
    },
  },
});

// The result is a strongly typed object that matches the query.
console.log(JSON.strigify(filmsResult, null, 2));
/**
 * This will print:
 * {
 *   "buf.knit.demo.swapi.film.v1.FilmService": {
 *     "getFilms": {
 *        "films": [
 *           {
 *             "id": "1",
 *             "title": "A New Hope",
 *             "director": "George Lucas",
 *             "releaseDate": "1977-05-25",
 *             "characters": [{
 *               { "id": "1", "name": "Luke Skywalker" },
 *               { "id": "2", "name": "C-3PO" },
 *               ...
 *             }]
 *           }
 *        ]
 *     }
 *   }
 * }
 */

Status: Alpha

Knit is undergoing initial development and is not yet stable.

Legal

Offered under the Apache 2 license.