# customisable-imports-openapi-overlays-and-terraform-generation-improvements
Source: https://speakeasy.com/blog/customisable-imports-openapi-overlays-and-terraform-generation-improvements


Welcome to another edition of the Speakeasy Changelog. In this issue, we'll give you a sneak peek into our support for [OpenAPI Overlays](https://github.com/OAI/Overlay-Specification) and how we're leveraging them to help customers customize their SDKs and other generated artifacts without changing the underlying specification.

We'll also be diving into new DevEx improvements that let you customize SDK imports, as well as exciting Terraform releases, including Pulumi support!

Sound good?

Ok, let's go! 🚀

## OpenAPI Overlays

What is an Overlay, you ask? You can think of them as miniature OpenAPI documents that can be used to customize certain details of your API without altering the source document.
Why would you want to maintain one?

- You might want to customize your OpenAPI spec for SDK creation, but changing your spec is hard because it's generated from an API framework like FastAPI, tsoa, JOI, etc.
- You have a lot of teams at your company creating OpenAPI specs, and asking one of them to make a change is a tough process.
- You are setting up a Terraform provider for your OSS product and need different server URLs configured so users only hit a hosted API.

Let's look at an example. Here's a simple spec for the Speakeasy bar with only two `tags` defined, `drinks` and `orders`.

```yaml
openapi: 3.1.0
info:
  title: The Speakeasy Bar
  version: 1.0.0
  summary: A bar that serves drinks.
servers:
  - url: https://speakeasy.bar
    description: The production server.
security:
  - apiKey: []
tags:
  - name: drinks
    description: The drinks endpoints.
  - name: orders
    description: The orders endpoints.
paths:
  /dinner/:
    post: ...
    get: ...
  /drinks/:
    post: ...
```

To make an easy-to-use SDK, we've decided that a public interface should use `snacks`, i.e., `sdk.snacks.get_orders()`. As the owner of the company's SDK, you want to make this change, but that would mean making an actual
code change with the team that owns the drinks and orders service. Worse yet, it's all microservices, and there is no one team that owns all the services. You can get around this sustainably with
an overlay.

This overlay includes a `target` that you want to modify in your source document and an `action` to modify the target.

```yaml
overlay: 1.0.0
info:
  title: Overlay to fix the Speakeasy bar
  version: 0.0.1
actions:
  - target: "$.tags"
    description: Add a Snacks tag to the global tags list
    update:
      - name: Snacks
        description: All methods related to serving snacks
  - target: "$.paths['/dinner']"
    description: Remove all paths related to serving dinner
    remove: true
```

Specify that we want to add a new tag to the global tags list `$.tags` and add a description of the edit you're making. Under the update label, add the name and description of the tag you want to add.
Now you can use the Speakeasy CLI to merge these two documents right before generating the SDK:

```bash
speakeasy overlay apply -s openapi.yaml -o overlay.yaml >> combined.yaml
```

Time to celebrate 🎉 You've just created a new OpenAPI document that you can use to generate an SDK with the `snacks` tag. More on how to use Overlays [here](/docs/prep-openapi/overlays/create-overlays).

## 📦 Customizable Imports

At Speakeasy, we believe that automated doesn't mean no input. Certain aspects of SDK design need to be in the hands of the API builders. That's why we've built a platform which is flexible enough to let developers craft the devex for their users. To that end, we've released customizable imports. You can now configure the structure of the `import` paths in your SDK, and how they are referenced by your users. As an example, for Typescript:

By default, our SDKs have created models in directories dictated by the OpenAPI spec:

- `models/components`
- `models/operations`
- `models/errors`

```yaml
sdk/
├─ models/
│  ├─ components/
│  │  ├─ user.ts
│  │  ├─ drink.ts
│  │  └─ ...
│  ├─ operations/
│  │  ├─ getuser.ts
│  │  ├─ updateuser.ts
│  │  ├─ getdrink.ts
│  │  ├─ updatedrink.ts
│  │  └─ ...
│  └─ errors/
│     ├─ sdkerror.ts
│     ├─ responseerror.ts
│     └─ ...
└─ ...
```

This is great for keeping your SDK organized, but it could be a bit verbose for your users, especially for less structured languages like Typescript and Python where global imports are the norm.

The import structure in this case would look like:

```typescript
import { SDK } from "@speakeasy/bar";
import { User } from "@speakeasy/bar/dist/models/components/user";
import { GetDrinkRequest } from "@speakeasy/bar/dist/models/operations/user";
```

As an API producer, you can now configure your SDK to generate models into a single directory and import them from there. For Typescript, this would result in:

```yaml
/
├─ src
│  ├─ models/
│  │  ├─ user.ts
│  │  ├─ drink.ts
│  │  ├─ getuser.ts
│  │  ├─ updateuser.ts
│  │  ├─ getdrink.ts
│  │  ├─ updatedrink.ts
│  │  ├─ sdkerror.ts
│  │  ├─ responseerror.ts
│  │  ├─ index.ts
│  │  └─ ...
│  └─ ...
└─ ...
```

This results in an import structure that is flat and supports a global path as follows:

```typescript
import { GetDrinkRequest, SDK, User } from "@speakeasy/bar";
```

More documentation on how to configure this in your SDK's `gen.yaml` file can be found [here](/docs/customize-sdks/imports).

## 🚢 Improvements and Bug Fixes 🐛

#### [Speakeasy v119.1](https://github.com/speakeasy-api/speakeasy/releases/tag/v1.119.1)

### Terraform

🚢 Pulumi support for generated Terraform providers\
🚢 Importing resources with Integer IDs\
🚢 DataSources with no required arguments (Empty Datasources)\
🚢 `x-speakeasy-conflicts-with` extension

### Python

🚢 Oauth support for Python SDKs

### Php

🚢 Support for customizable imports

### Typescript

🐛 Ensure `contentType` variable doesn't conflict with common parameter names\
🐛 Correctly handle `x-www-form-urlencode` in Typescript\
🚢 unset baseURL on default axios client

### Golang

🐛 `BigInt` & `Decimal` type support within a `Union` type

### Other:

🚢 Allow optional properties in usage snippets to be conditionally rendered\
🚢 Support for customizing input/output model suffixes\
🚢 Maintain OpenAPI Order in generated models\
🚢 Automatic Authentication documentation generated in READMEs\
🚢 Automatic Retry documentation generated in READMEs when retry extensions are used