---
title: Long-Running Operations
llmstxt: true
---

import { ClientTabs, ClientTabItem } from "@components/client-tabs";

This doc details what emitters will generate for long-running operations.

## Resource create or replace

Long-running operation to create or replace a resource.

<ClientTabs>

```typespec
alias ResourceOperations = global.Azure.Core.ResourceOperations<NoConditionalRequests &
  NoRepeatableRequests &
  NoClientRequestId>;

/** Details about a user. */
@resource("users")
model User {
  /** The name of user. */
  @key
  @visibility(Lifecycle.Read)
  name: string;

  /** The role of user */
  role: string;
}

// Operation for polling the status of the LRO. SDK may exclude this operation from client.
@sharedRoute
op getOperationStatus is ResourceOperations.GetResourceOperationStatus<User, never>;

/** Create or replace the User. */
@pollingOperation(getOperationStatus)
op createOrReplace is ResourceOperations.LongRunningResourceCreateOrReplace<User>;
```

```python
def begin_create_or_replace(
    self, name: str, resource: Union[User, JSON, IO[bytes]], **kwargs: Any
) -> LROPoller[User]
```

```csharp
public virtual Operation<User> CreateOrReplace(WaitUntil waitUntil, string name, User resource, CancellationToken cancellationToken = default);
public virtual Task<Operation<User>> CreateOrReplaceAsync(WaitUntil waitUntil, string name, User resource, CancellationToken cancellationToken = default);
```

```typescript
// JS CodeGen api layer
export function createOrReplace(
  context: Client,
  name: string,
  resource: User,
  options: CreateOrReplaceOptionalParams = { requestOptions: {} }
): PollerLike<OperationState<User>, User>;

export async function getOperationStatus(
  context: Client,
  name: string,
  operationId: string,
  options: GetOperationStatusOptionalParams = { requestOptions: {} }
): Promise<User>;

// JS CodeGen classical client layer
export class TestServiceClient {
  createOrReplace(
    name: string,
    resource: User,
    options: CreateOrReplaceOptionalParams = { requestOptions: {} }
  ): PollerLike<OperationState<User>, User>；

  getOperationStatus(
    name: string,
    operationId: string,
    options: GetOperationStatusOptionalParams = { requestOptions: {} }
  ): Promise<User>;
}
```

```java
public SyncPoller<PollOperationDetails, User> beginCreateOrReplace(String name, User resource);
```

```go
func (c *Client) BeginCreateOrReplaceUser(ctx context.Context, name string, body User) (*runtime.Poller[User], error)
```

</ClientTabs>

## Resource delete

Long-running operation to delete a resource.

<ClientTabs>

```typespec
alias ResourceOperations = global.Azure.Core.ResourceOperations<NoConditionalRequests &
  NoRepeatableRequests &
  NoClientRequestId>;

/** Details about a user. */
@resource("users")
model User {
  /** The name of user. */
  @key
  @visibility(Lifecycle.Read)
  name: string;

  /** The role of user */
  role: string;
}

// Operation for polling the status of the LRO. SDK may exclude this operation from client.
@sharedRoute
op getOperationStatus is ResourceOperations.GetResourceOperationStatus<User, never>;

/** Delete the User. */
@pollingOperation(getOperationStatus)
op delete is ResourceOperations.LongRunningResourceDelete<User>;
```

```python
def begin_delete(self, name: str, **kwargs: Any) -> LROPoller[None]
```

```csharp
public virtual Operation Delete(WaitUntil waitUntil, string name, CancellationToken cancellationToken = default);
public virtual Task<Operation> DeleteAsync(WaitUntil waitUntil, string name, CancellationToken cancellationToken = default);
```

```typescript
// JS CodeGen api layer
export function $delete(
  context: Client,
  name: string,
  options: DeleteOptionalParams = { requestOptions: {} },
): PollerLike<OperationState<void>, void>;

export async function getOperationStatus(
  context: Client,
  name: string,
  operationId: string,
  options: GetOperationStatusOptionalParams = { requestOptions: {} },
): Promise<void>;

// JS CodeGen classical client layer
export class TestServiceClient {
  delete(
    name: string,
    options: DeleteOptionalParams = { requestOptions: {} },
  ): PollerLike<OperationState<void>, void>；

  getOperationStatus(
    name: string,
    operationId: string,
    options: GetOperationStatusOptionalParams = { requestOptions: {} },
  ): Promise<void>;
}
```

```java
public SyncPoller<PollOperationDetails, Void> beginDelete(String name);
```

```go
func (c *Client) BeginDeleteUser(ctx context.Context, name string, options *DeleteUserOptions) (*runtime.Poller[User], error)
```

</ClientTabs>

## Resource action

Long-running operation to invoke an action on a resource.

<ClientTabs>

```typespec
alias ResourceOperations = global.Azure.Core.ResourceOperations<NoConditionalRequests &
  NoRepeatableRequests &
  NoClientRequestId>;

/** Details about a user. */
@resource("users")
model User {
  /** The name of user. */
  @key
  @visibility(Lifecycle.Read)
  name: string;

  /** The role of user */
  role: string;
}

/** The parameters for exporting a user. */
model UserExportParams {
  /** The format of the data. */
  @query
  format: string;
}

/** The exported user data. */
model ExportedUser {
  /** The name of user. */
  name: string;

  /** The exported URI. */
  resourceUri: string;
}

// Operation for polling the status of the LRO. SDK may exclude this operation from client.
@sharedRoute
op getExportOperationStatus is ResourceOperations.GetResourceOperationStatus<User, ExportedUser>;

/** Action to export the data of the User. */
@pollingOperation(getExportOperationStatus)
op export is ResourceOperations.LongRunningResourceAction<User, UserExportParams, ExportedUser>;
```

```python
def begin_export(self, name: str, *, format: str, **kwargs: Any) -> LROPoller[ExportedUser]
```

```csharp
public virtual Operation<ExportedUser> Export(WaitUntil waitUntil, string name, string format, CancellationToken cancellationToken = default);
public virtual Task<Operation<ExportedUser>> ExportAsync(WaitUntil waitUntil, string name, string format, CancellationToken cancellationToken = default);
```

```typescript
// JS CodeGen api layer
export function $export(
  context: Client,
  name: string,
  format: string,
  options: ExportOptionalParams = { requestOptions: {} },
): PollerLike<OperationState<ExportedUser>, ExportedUser>;

export async function getExportOperationStatus(
  context: Client,
  name: string,
  operationId: string,
  options: GetExportOperationStatusOptionalParams = { requestOptions: {} },
): Promise<ExportedUser>;

// JS CodeGen classical client layer
export class TestServiceClient {
  export(
    name: string,
    format: string,
    options: ExportOptionalParams = { requestOptions: {} },
  ): PollerLike<OperationState<ExportedUser>, ExportedUser>；

  getExportOperationStatus(
    name: string,
    operationId: string,
    options: GetExportOperationStatusOptionalParams = { requestOptions: {} },
  ): Promise<ExportedUser>;
}
```

```java
public SyncPoller<PollOperationDetails, ExportedUser> beginExport(String name, String format);
```

```go
func (c *Client) BeginExportUser(ctx context.Context, name string, format string, options *ExportUserOptions) (*runtime.Poller[ExportedUser], error)
```

</ClientTabs>

## Legacy LRO Decorators

:::caution
The decorators in this section are in the `Azure.ClientGenerator.Core.Legacy` namespace and should only be used for legacy compatibility scenarios.
:::

### Forcing an operation to be treated as long-running (`@markAsLro`)

If you have an operation that should be treated as a long-running operation but isn't recognized as one by default, you can force it using `@markAsLro`. The operation's return type must be a `Model`.

```tsp
import "@azure-tools/typespec-client-generator-core";

using Azure.ClientGenerator.Core.Legacy;

model OperationResult {
  id: string;
  status: string;
}

@markAsLro
@post
op startProcessing(): OperationResult;
```
