> Markdown version of [TypeScript Generator](https://vaadin.com/docs/next/hilla/reference/typescript-generator). Section index: [llms.txt](https://vaadin.com/docs/next/hilla/llms.txt)

# TypeScript Generator

The TypeScript generator produces TypeScript files that map to Java services annotated with `@BrowserCallable` or `@Endpoint`. These files retain the properties and types of the Java classes to provide type safety in the frontend.

<!-- vale Vaadin.BrowserCallableService = NO -->

These annotated services were previously called **endpoints**. That name is misleading — Hilla has a single REST endpoint, which in turn calls the browser-callable services — so this documentation calls them browser-callable services.

<!-- vale Vaadin.BrowserCallableService = YES -->

## <a id="features"></a>Features

The generator has support for multi-module projects. You can use standard Maven modules in your application, or even external dependencies, as there is no need for the services and entity classes to be in the same project as the Hilla application.

The generator is designed to be flexible. All parts of the generator are pluggable, which allows you to alter the default behavior or add a new one.

> **Note:** Spring Boot enables a Java compiler option to retain parameter names in class files. If generated classes are missing parameter names, you might need to enable this option in your project. Use the `javac -parameters` option to enable support for multi-module projects and all JVM languages. See [Configuration](https://vaadin.com/docs/next/hilla/reference/configuration.md#java-compiler-options) for details.

## <a id="generator-architecture"></a>Generator Architecture

The generator consists of three parts:

- **Java bytecode parser**

  The parser reads the Java bytecode and generates an OpenAPI scheme.

- **TypeScript Abstract Syntax Tree (AST) generator**

  The AST generator reads the OpenAPI scheme and generates the TypeScript clients that could be used in further frontend development.

- **Runtime controller**

  The runtime controller provides runtime communication between the server and the client.

Hilla uses the [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification) as a middle layer between the Java services and their TypeScript clients. The implementation is based on OpenAPI specification 3.0. For details, see [the appendix at the end of this page](#appendix).

## <a id="examples"></a>Examples

### <a id="generated-typescript-client"></a>Generated TypeScript Client

The `UserService.ts` class is generated from the `UserService.java` class.

`UserService.ts`

```typescript
/**
 * User service.
 *
 * This module has been generated from UserService.java
 * @module UserService
 */
import client from './connect-client.default'; // (1)

/**
 * Check if a user is admin or not.
 *
 * @param id User id to be checked
 * Return Return true if the given user is an admin, otherwise false.
 */
export async function isAdmin( // (2)
  id?: number
) {
  return await client.call('UserService', 'isAdmin', {id});
}
```

`UserService.java`

```java
/**
 * User service.
 */
@BrowserCallable
public class UserService {
    /**
     * Check if a user is admin or not.
     *
     * @param id
     *            User id to be checked
     * @return Return true if the given user is an admin, otherwise false.
     */
    public boolean isAdmin(long id) {
        return id == 0;
    }
}
```

1. This line is a static part of any generated TypeScript class. `connect-client.default.ts` is another generated file, which includes default configurations for the `ConnectClient` and exports its instance as `client`.

2. Each method in the generated TypeScript class corresponds to a Java method in the `@BrowserCallable`-annotated class.

For more information about type mapping between Java and TypeScript, see [Type conversion](https://vaadin.com/docs/next/hilla/reference/type-conversion.md). You may also want to learn about [Type nullability](https://vaadin.com/docs/next/hilla/reference/type-nullability.md).

## <a id="appendix"></a>Appendix: How a TypeScript class is generated from the OpenAPI specification

### <a id="modules-classes"></a>Modules / Classes

The generator collects all the `tags` fields of all operations in the OpenAPI document. Each tag generates a corresponding TypeScript file. The tag name is used for TypeScript module/class name, as well as the file name.

### <a id="methods"></a>Methods

Each exported method in a module corresponds to a [POST operation](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject) of a [path item](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#pathItemObject) in [paths object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#pathsObject).

> **Note:** The generator only supports the `POST` operation. If a path item contains operations other than `POST`, the generator stops processing.

The path **must** start with `/`, as described in [Patterned Fields](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#patterned-fields). It’s parsed as `/<service name>/<method name>`, which is used as a parameter to call the Java services in the backend. The method name from the path is also reused as the method name in the generated TypeScript file.

#### <a id="method-parameters"></a>Method Parameters

The parameters of the method are taken from the `application/json` content of the [request body object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#requestBodyObject).

To get the result as [`UserService.ts`](#user-service-ts), the request body content should be:

Request body

```json
{
 "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number"
          }
        }
      }
    }
  }
}
```

> **Note:** All the other content types of the request body object are ignored by the Hilla generator. This means that a method that doesn’t have the `application/json` content type is considered to be one with no parameters.

#### <a id="method-return-type"></a>Method Return Type

The return type is taken from the `200` [response object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject). As with the request body object, the generator is only interested in the `application/json` content type.

Here’s an example of a [response object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject):

Response object

```json
{
  "200": {
    "description": "Return true if the given user is an admin, otherwise false.",
    "content": {
      "application/json": {
        "schema": {
          "type": "boolean"
        }
      }
    }
  }
}
```

> **Note:** Currently, the generator only recognizes `200` response objects. Other response objects are ignored.

Post Operation

```json
{
  "tags": ["UserService"], // (1)
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "id": {
              "type": "number"
            }
          }
        }
      }
    }
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "type": "boolean"
          }
        }
      }
    }
  }
}
```

1. As mentioned in the [operation object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject) specification, in the Hilla generator, `tags` are used to classify operations into TypeScript files. This means that each tag has a corresponding generated TypeScript file. Operations that contain more than one tag appear in all the generated files. Operations with empty tags are placed in the `Default.ts` file.

> **Note:** Although multiple tags don’t break the generator, it might be confusing at development time if there are two identical methods in different TypeScript files. It’s recommended to have only one tag per operation.

Here is an example OpenAPI document that could generate previous `UserService.ts`:

User service OpenAPI document

```json
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "My example application",
    "version" : "1.0.0"
  },
  "servers" : [ {
    "url" : "https://myhost.com/myservice"
  } ],
  "tags" : [ {
    "name" : "UserService"
  } ],
  "paths" : {
    "/UserService/isAdmin" : {
      "post": {
        "tags": ["UserService"],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [ "id" ],
                "properties": {
                  "id": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      }
    }
  }
}
```
