Paging Operations
This doc details what emitters will generate for paging operations.
Using next link to indicate how to get the next page
Section titled “Using next link to indicate how to get the next page”Next link is an absolute url returned by the paging operation, which indicates how to get the next page.
If the response does not return a next link, it indicates the last page of results.
Next link should be annotated in the response model with @nextLink.
There are two ways to indicate a paging operation with @nextLink:
- Use
@list,@nextLinkand@items
@list op listWithPage(): UserList;
model User { id: string; name: string;}
model UserList { @pageItems value: User[];
@nextLink nextLink?: url;}class User(_model_base.Model): id: str = rest_field() name: str = rest_field()
def list_with_page(self, **kwargs: Any) -> ItemPaged["_models.User"]: ...public virtual Pageable<User> ListWithPage(CancellationToken cancellationToken = default);export interface ListWithPageOptionalParams extends OperationOptions {}// JS CodeGen api layerexport function listWithPage( context: Client, options: ListWithPageOptionalParams = { requestOptions: {} },): PagedAsyncIterableIterator<User>;
// JS CodeGen classical client layerexport class TestServiceClient { listWithPage( options: ListWithPageOptionalParams = { requestOptions: {} }, ): PagedAsyncIterableIterator<User>;}public PagedIterable<User> listWithPage();type User struct { ID string `json:"id"` Name string `json:"name"`}
type UserList struct { Value []User NextLink *string}
func (c *Client) ListWithPage(ctx context.Context) (UserList, error)- Use the
@listand@pageItemsdecorators from TypeSpec core.
@listop listWithPage(): UserList;
model User { id: string; name: string;}
model UserList { @pageItems value: User[];
@nextLink nextLink?: url;}class User(_model_base.Model): id: str = rest_field() name: str = rest_field()
def list_with_page(self, **kwargs: Any) -> ItemPaged["_models.User"]: ...public virtual Pageable<User> ListWithPage(CancellationToken cancellationToken = default);// JS CodeGen api layerexport function listWithPage( context: Client, options: ListWithPageOptionalParams = { requestOptions: {} },): PagedAsyncIterableIterator<User>;
// JS CodeGen classical client layerexport class TestServiceClient { listWithPage( options: ListWithPageOptionalParams = { requestOptions: {} }, ): PagedAsyncIterableIterator<User>;}public PagedIterable<User> listWithPage();type User struct { ID string Name string}
type UserList struct { Value []User NextLink *string}
func (c *Client) ListWithPage(ctx context.Context) (UserList, error)Using continuation token to indicate how to get the next page
Section titled “Using continuation token to indicate how to get the next page”A continuation token is a string returned by a paging operation, which is used as a parameter value for the paging operation to get the next page.
If the response does not return a continuation token, it indicates the last page of results.
The request parameter that corresponds to the continuation token value in the paging operation should be decorated with @continuationToken. Similarly, the response property that contains the continuation token value should also be decorated with @continuationToken.
- Continuation token in query parameter and response body.
@listop listWithPage(@query @continuationToken continuationToken?: string): UserList;
model User { id: string; name: string;}
model UserList { @pageItems value: User[];
@continuationToken continuationToken?: string;}class User(_model_base.Model): id: str = rest_field() name: str = rest_field()
def list_with_page(self, **kwargs: Any) -> ItemPaged["_models.User"]: ...// TODO// JS CodeGen api layerexport function listWithPage( context: Client, options: ListWithPageOptionalParams = { requestOptions: {} },): PagedAsyncIterableIterator<User>;
// JS CodeGen classical client layerexport class TestServiceClient { listWithPage( options: ListWithPageOptionalParams = { requestOptions: {} }, ): PagedAsyncIterableIterator<User>;}NOT_SUPPORTED// NOT_SUPPORTED- Continuation token in header parameter and response body.
@listop listWithPage(@header @continuationToken continuationToken?: string): UserList;
model User { id: string; name: string;}
model UserList { @pageItems value: User[];
@continuationToken continuationToken?: string;}class User(_model_base.Model): id: str = rest_field() name: str = rest_field()
def list_with_page(self, **kwargs: Any) -> ItemPaged["_models.User"]: ...// TODO// JS CodeGen api layerexport function listWithPage( context: Client, options: ListWithPageOptionalParams = { requestOptions: {} },): PagedAsyncIterableIterator<User>;
// JS CodeGen classical client layerexport class TestServiceClient { listWithPage( options: ListWithPageOptionalParams = { requestOptions: {} }, ): PagedAsyncIterableIterator<User>;}NOT_SUPPORTED// NOT_SUPPORTED- Continuation token in query parameter and response header.
@listop listWithPage(@query @continuationToken continuationToken?: string): { @header @continuationToken continuationToken?: string;
@pageItems value: User[];};
model User { id: string; name: string;}class User(_model_base.Model): id: str = rest_field() name: str = rest_field()
def list_with_page(self, **kwargs: Any) -> ItemPaged["_models.User"]: ...// TODO// JS CodeGen api layerexport function listWithPage( context: Client, options: ListWithPageOptionalParams = { requestOptions: {} },): PagedAsyncIterableIterator<User>;
// JS CodeGen classical client layerexport class TestServiceClient { listWithPage( options: ListWithPageOptionalParams = { requestOptions: {} }, ): PagedAsyncIterableIterator<User>;}NOT_SUPPORTED// NOT_SUPPORTED- Continuation token in header parameter and response header.
@listop listWithPage(@query @continuationToken continuationToken?: string): { @header @continuationToken continuationToken?: string;
@pageItems value: User[];};
model User { id: string; name: string;}class User(_model_base.Model): id: str = rest_field() name: str = rest_field()
def list_with_page(self, **kwargs: Any) -> ItemPaged["_models.User"]: ...// TODO// JS CodeGen api layerexport function listWithPage( context: Client, options: ListWithPageOptionalParams = { requestOptions: {} },): PagedAsyncIterableIterator<User>;
// JS CodeGen classical client layerexport class TestServiceClient { listWithPage( options: ListWithPageOptionalParams = { requestOptions: {} }, ): PagedAsyncIterableIterator<User>;}NOT_SUPPORTED// NOT_SUPPORTEDAdvanced
Section titled “Advanced”Parameterized next links (against guidelines)
Section titled “Parameterized next links (against guidelines)”In very rare cases, there are cases of next links that require parameterization. These cases exist outside of the Azure guidelines for paging, but must be supported for legacy reasons.
In cases like this, you may use the special scalar type Azure.Core.Legacy.parameterizedNextLink. You can specify which parameters must be reformatted into the next link. Your emitted SDK will handle the reformatting based on the tsp definition
model ListCertificateOptions { includePending?: string;}model Certificate { name: string;}model Page { @pageItems items: Certificate[]; @nextLink nextLink: Azure.Core.Legacy.parameterizedNextLink<[ ListCertificateOptions.includePending ]>;}Legacy Paging Decorators
Section titled “Legacy Paging Decorators”Forcing an operation to be treated as pageable (@markAsPageable)
Section titled “Forcing an operation to be treated as pageable (@markAsPageable)”If you have an operation that returns a paged result but isn’t recognized as a paging operation by default (e.g., it doesn’t use @list), you can force it to be treated as a pageable operation using @markAsPageable.
The decorator will look for a property decorated with @pageItems in the response model. If no such property exists, it will look for a property named value. If neither is found, a warning is emitted.
import "@azure-tools/typespec-client-generator-core";
using Azure.ClientGenerator.Core.Legacy;
@markAsPageableop listItems(): { @pageItems items: Widget[]; nextLink?: string;};Disabling paging for an operation (@disablePageable)
Section titled “Disabling paging for an operation (@disablePageable)”If an operation is automatically detected as a paging operation (e.g., because it uses @list) but you don’t want it treated as pageable in the generated client, use @disablePageable.
import "@azure-tools/typespec-client-generator-core";
using Azure.ClientGenerator.Core.Legacy;
@disablePageable@listop listItems(): { @pageItems items: Widget[]; nextLink?: string;};Specifying the HTTP verb for next link requests (@nextLinkVerb)
Section titled “Specifying the HTTP verb for next link requests (@nextLinkVerb)”By default, the next link request uses a GET verb. If your service requires a POST verb for fetching subsequent pages, use @nextLinkVerb.
import "@azure-tools/typespec-client-generator-core";
using Azure.ClientGenerator.Core.Legacy;
@nextLinkVerb("POST")@listop listItems(): { @pageItems items: Widget[]; @nextLink nextLink?: string;};