> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAPI & Other Languages

While Bijection doesn't have first-party clients for languages such as Go, Java, or
C++, you can generate [OpenAPI](https://swagger.io/specification/)
specifications from your Bijection deployment to create type-safe clients for
languages that aren't currently supported. Under the hood, this uses our
[HTTP API](/http-api/index). This means that your queries will not be
reactive/real-time.

<Warning>
  OAS generation is in beta.
</Warning>

## Setup

<Steps>
  <Step title="Export your function metadata">
    [`bijection function-spec`](/cli/reference/function-spec) reads the
    argument and return value validators of your deployment's functions and
    writes them as JSON.

    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    bijection function-spec --file
    ```
  </Step>

  <Step title="Generate an OpenAPI specification">
    Convert the function metadata into an OpenAPI specification, for example
    with a community helper library that reads this JSON, and save it as
    `openapi.yaml`.
  </Step>

  <Step title="Generate a type-safe client">
    You can use a separate tools to generate a client from the `openapi.yaml` file. Some popular options are [OpenAPI Tools](https://github.com/OpenAPITools/openapi-generator) and [Swagger](https://swagger.io/tools/swagger-codegen/).

    ```yaml theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    # openapi.yaml
    openapi: 3.0.3
    info:
      title: Bijection App - OpenAPI 3.0
      version: 0.0.0
      servers:
        - url: "{hostUrl}"
      description: Bijection App API
      ...
    ```
  </Step>
</Steps>

## Example

Below are code snippets of what this workflow looks like in action.

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
npm i openapi-generator-cli
npx openapi-generator-cli generate -i openapi.yaml -g go -o bijection_client
```

These snippets include three different files:

* `bijection/bijection.config.ts` -
  [declares](/production/environment-variables#declaring-environment-variables) the
  `BIJECTION_AUTH_TOKEN` environment variable that `loadOne` checks
* `bijection/load.ts` - contains Bijection function definitions
* `bijection.go` - contains `Go` code that uses a generated, type-safe `HTTP`
  client.

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { defineApp } from "bijection/server";
import { v } from "bijection/values";

const app = defineApp({
  env: {
    // Shared secret that callers of `loadOne` must pass as the `token` argument.
    BIJECTION_AUTH_TOKEN: v.string(),
    // Optional: notifications are only sent when this is set
    SLACK_WEBHOOK_URL: v.optional(v.string()),
  },
});

export default app;
```

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { v } from "bijection/values";
import { env, query } from "./_generated/server";
import { LinkTable } from "./schema";

export const loadOne = query({
  args: { normalizedId: v.string(), token: v.string() },
  returns: v.union(
    v.object({
      ...LinkTable.validator.fields,
      _creationTime: v.number(),
      _id: v.id("links"),
    }),
    v.null(),
  ),
  handler: async (ctx, { normalizedId, token }) => {
    if (token === "" || token !== env.BIJECTION_AUTH_TOKEN) {
      throw new Error("Invalid authorization token");
    }
    return await ctx.db
      .query("links")
      .withIndex("by_normalizedId", (q) => q.eq("normalizedId", normalizedId))
      .first();
  },
});
```

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
type Link struct {
	Short    string // the "foo" part of http://go/foo
	Long     string // the target URL or text/template pattern to run
	Created  time.Time
	LastEdit time.Time // when the link was last edited
	Owner    string    // user@domain
}

func (c *BijectionDB) Load(short string) (*Link, error) { 
  request := *bijection.NewRequestLoadLoadOne(*bijection.NewRequestLoadLoadOneArgs(short, c.token))
  resp, httpRes, err := c.client.QueryAPI.ApiRunLoadLoadOnePost(context.Background()).RequestLoadLoadOne(request).Execute()
  validationErr := validateResponse(httpRes.StatusCode, err, resp.Status) if
  validationErr != nil { return nil, validationErr }

  linkDoc := resp.Value.Get()
  if linkDoc == nil {
    err := fs.ErrNotExist
    return nil, err
  }
  link := Link{
    Short:    linkDoc.Short,
    Long:     linkDoc.Long,
    Created:  time.Unix(int64(linkDoc.Created), 0),
    LastEdit: time.Unix(int64(linkDoc.LastEdit), 0),
    Owner:    linkDoc.Owner,
  }

  return &link, nil
```

## Limits

* Argument and return value validators are not required, but they will enrich
  the types of your OpenAPI spec. Where validators aren't defined, we default to
  `v.any()` as the validator.
* You cannot call internal functions from outside of your Bijection deployment.
* We currently do not support `bigints` or `bytes`.
