Customize Namespaces

When you're exposing your API to users, you may want to group API methods into namespaces to give your SDK an object-oriented interface. This type of interface can help users to better conceptualize the objects they are manipulating when they use the API.

Default Behavior

By default, Speakeasy will use the tags in your OpenAPI spec as the organizing principles for namespaces. For each tag in your spec, a namespace will be created.

Each method will be then be added to namespaces corresponding with its tags. If a method does not have an associated tag, then it will be added to the root sdk class of the generated client library. In the case where multiple tags are associated, the operation will appear as a method in multiple classes.

The example below shows one method added to a namespace, and another left to the default class:

paths:
  /bar_locations:
    get:
    operationId: listLocations
    summary: List all locations of the Speakeasy bar
    description: Get a list of all the bars being run by Speakeasy
    responses:
      "200":
        description: A list of bars
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/BarLocation"
  /drinks:
    get:
      operationId: listDrinks
      summary: List all drinks
      description: Get a list of all drinks served by the bar
      tags:
        - drinks
      responses:
        "200":
          description: A list of drinks
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Drink"
tags:
  - name: drinks
    description: Everything about our Drinks on offer

The generated SDK will have methods invocable like so:

// ListDrinks - List all Drink
// Get a list of all pets in the system
sdk.Drinks.ListDrinks()
sdk.ListLocations()

x-speakeasy-group - Define Namespaces Without Tags

Sometimes the tags in an OpenAPI spec may already be used for an unrelated purpose (for example autogenerating documentation). In this scenario, you may want to use something other than tags to organize your methods.

For this scenario, we support a x-speakeasy-group field which allows you to define custom namespaces. This field can be added to any operation in your OpenAPI spec. If added, x-speakeasy-group overrides any tags associated to that particular method:

paths:
  /drinks/{drink_type}/get_vintage:
    get:
      operationId: getVintage
      summary: Check the vintage of the wine
      description: Get the vintage of a drinks served by the bar
      parameters:
        - name: drink_type
          in: path
          description: The type of drink
          required: true
          schema:
            type: string
      tags:
        - drinks
      x-speakeasy-group: wine
      responses:
        "200":
          description: A list of drinks
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Drink"
tags:
  - name: drinks
    description: Everything about Drinks on offer

The generated SDK will have a method invocable like so:

// GetVintage - get the vintage of the wine
sdk.wine.GetVintage("wine")

Define Multi-Level Namespaces

You can use tags or the x-speakeasy-group extension to define nested namespaces for your operations using . notion. There is no limit to the number of levels you can define.

paths:
  /drink/{drink_type}/get_vintage/:
    get:
      operationId: getVintage
      summary: Check the vintage of the wine
      tags: 
        - drinks.wine
      parameters:
        - name: drink_type
          in: path
          description: The type of drink
          required: true
          schema:
            type: string
      responses:
        "200":
          description: the wine vintage
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Vintage"

The generated SDK will have a method invocable like so:

// Get the Vintage
sdk.Drinks.Wine.GetVintage("wine")

Handling Multiple Namespaces

By default if your spec lists multiple values in tags or x-speakeasy-group the operation will be added to multiple namespaces:

paths:
  /drink/{drink_type}/get_vintage/:
    get:
      operationId: getVintage
      summary: Check the vintage of the wine
      tags: 
        - drinks
        - wine
      parameters:
        - name: drink_type
          in: path
          description: The type of drink
          required: true
          schema:
            type: string
      responses:
        "200":
          description: the wine vintage
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Vintage"
// Get the Vintage
sdk.Drinks.GetVintage("wine")
sdk.Wine.GetVintage("wine")

However, you can disable this default behavior. Simply modify your SDK's gen.yaml file and add the following line:

# ...
generation:
  tagNamespacingDisabled: true

With the tagNamespacingDisabled flag set to true, the following operation will only be added to the first namespace listed in tags or x-speakeasy-group.

paths:
  /drink/{drink_type}/get_vintage/:
    get:
      operationId: getVintage
      summary: Check the vintage of the wine
      tags: 
        - drinks
        - wine
      parameters:
        - name: drink_type
          in: path
          description: The type of drink
          required: true
          schema:
            type: string
      responses:
        "200":
          description: the wine vintage
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Vintage"