# OpenAPI Integration

> Learn how to embed Taxi semantic types in OpenAPI specifications

Source: https://taxilang.org/docs/other-api-specs/open-api

## Overview

Taxi can be embedded within OpenAPI specifications to add semantic meaning to APIs. This allows you to:
- Define semantic types for request/response models
- Add semantic meaning to API parameters
- Create a unified semantic layer across multiple APIs

> **Note: Semantic Enhancement**
>
> OpenAPI specs describe API structure. Taxi enhances them with semantic meaning, enabling better data discovery and integration.

## Adding Taxi to OpenAPI

### Basic Syntax

Taxi metadata is added using `x-taxi-type` extensions in your OpenAPI spec:

```yaml
x-taxi-type:
  name: com.acme.MyType    # The semantic type name
  create: false            # Optional flag to control type creation
```

### Type Creation Behavior

The `create` flag controls whether new types are created if they don't exist.

The default behaviour varies between models and field attributes - and defaults to the reccomended best practice
for each.

| Context          | Default | Behavior                       |
|------------------|---------|--------------------------------|
| Response Models  | `true`  | Creates new types if not found |
| Field Attributes | `false` | Requires types to exist        |

> **Note: Type Creation**
>
> Semantic types let you share data between systems, while avoiding tight coupling. Try to use existing types (where the semantics match), or create new types in a shared taxonomy - rather than creating types in your OpenAPI spec
> Only create new types (`create: true`) when you're intentionally extending your semantic model, or creating a type you're not ready to share yet.

### Declaring operation kinds
Some TaxiQL behavior depends on whether operations are read-only or write operations (sometimes referred to as 'mutations').

By default:
- **GET**, **HEAD**, and **OPTIONS** methods are treated as **read** operations (default, no modifier)
- **POST**, **PUT**, **PATCH**, and **DELETE** methods are treated as **write** operations

You can override this default behavior using `x-taxi-operation-kind` at the operation level:

```yaml
   openapi: "3.0.0"
   info:
     version: 1.0.0
     title: Swagger Petstore
   paths:
     /pets:
       # POST operations are 'write' by default, but this can be overridden
       post:
         x-taxi-operation-kind: read  # Override to make a POST operation read-only
         responses:
           '200':
             description: successful operation
             content:
               application/json:
                 schema:
                   type: object
                   properties:
                     name:
                       type: string
       
       # GET operations are 'read' by default, but this can be overridden
       get:
         x-taxi-operation-kind: write  # Override to make a GET operation a write operation
         responses:
           '200':
             description: successful operation
             content:
               application/json:
                 schema:
                   type: object
                   properties:
                     name:
                       type: string
```

Possible values for `x-taxi-operation-kind`:
- `read` - The operation is read-only (default for GET, HEAD, OPTIONS)
- `write` - The operation modifies data (default for POST, PUT, PATCH, DELETE)

## Enriching OpenAPI Components

### Response Models

Add semantic meaning to response types:

```yaml
   components:
     schemas:
       Customer:
>        x-taxi-type:
>          name: acme.Customer
         properties:
           id: 
             type: string
>            x-taxi-type:
>              name: acme.CustomerId
           email:
             type: string
>            x-taxi-type:
>              name: acme.EmailAddress
```

### Input Parameters

Enrich API parameters with semantic types:

```yaml
   paths:
     /customers/{id}:
       get:
         parameters:
           - name: id
             in: path
             schema:
               type: string
>              x-taxi-type:
>                name: acme.CustomerId
```

### Field Attributes

Add semantic meaning to model fields:

```yaml
   components:
     schemas:
       Customer:
         properties:
           name:
             type: string
>            x-taxi-type:
>              name: acme.CustomerName
>              # Only create if type doesn't exist
>              create: true
```
