The /auto pages provide a schema-driven browser and CRUD UI for the AutoQuery data models available to the current user. They are served by ServiceStack's existing MetadataFeature; no separate plugin or frontend build is required.
Open /auto to browse models, or /auto/{ModelName} to work with a specific model:
Routes​
| Route | Response |
|---|---|
GET /auto |
Searchable HTML catalog of available AutoQuery models |
GET /auto.json |
Model catalog as JSON |
GET /auto/{ModelName} |
HTML query and CRUD UI for a model |
GET /auto/{ModelName}.json |
Model-level AutoQuery schema |
The catalog and individual schemas are generated for each request. Models and operations that are not available to the current authenticated user are omitted.
Requirements​
The UI is available in .NET 8+ ServiceStack Apps that have:
MetadataFeatureenabled- A registered AutoQuery feature
- At least one AutoQuery Query API
A model needs an authorized Query API to appear in /auto. Create, Update, Patch, Delete and Save controls are added only when corresponding authorized AutoQuery CRUD APIs exist.
For example, these services produce a query grid with Create, Patch and Delete actions:
public class QueryBookings : QueryDb<Booking> {}
public class CreateBooking : ICreateDb<Booking>, IReturn<IdResponse>
{
public string Name { get; set; }
public RoomType RoomType { get; set; }
public DateTime BookingStartDate { get; set; }
public DateTime BookingEndDate { get; set; }
}
public class UpdateBooking : IPatchDb<Booking>, IReturn<IdResponse>
{
public int Id { get; set; }
public string? Name { get; set; }
}
public class DeleteBooking : IDeleteDb<Booking>, IReturnVoid
{
public int Id { get; set; }
}
Model schema​
/auto/Booking.json returns a model envelope containing the data model and the API schemas used to operate on it:
{
"name": "Booking",
"title": "Booking",
"primaryKey": "Id",
"model": { "type": "object", "properties": {} },
"query": { "$id": "/api/QueryBookings", "method": "GET", "operation": "Query" },
"create": { "$id": "/api/CreateBooking", "method": "POST", "operation": "Create" },
"update": { "$id": "/api/UpdateBooking", "method": "PATCH", "operation": "Patch" },
"delete": { "$id": "/api/DeleteBooking", "method": "DELETE", "operation": "Delete" }
}
| Member | Purpose |
|---|---|
name |
Data model type name |
title |
Display title derived from metadata or the model name |
primaryKey |
Property used to identify and deep-link rows |
model |
Writable model schema used by CRUD forms |
viewModel |
Optional projected result type for IQueryDb<From, Into> queries |
query |
Query API schema; required for the model to be listed |
create, update, delete, save |
Authorized write API schemas, when available |
Each operation is a complete API Schema, including its request fields, validation constraints, HTTP method, route and UI metadata.
Query UI​
The generated query view supports:
- Server-side paging and sorting
- AutoQuery filters and multiple filter expressions
- Selectable columns and page sizes
- Deep links through query-string state
- Per-model preferences stored in the browser
- Formatting supplied by
[Intl]and[Format]
For example:
Create, edit and delete​
Forms are generated independently from each write API. This is important when Create and Update DTOs expose different fields or validation rules.
- Create uses the
createschema. - Edit prefers Patch, then Update or Save when available.
- Patch sends changed fields only.
- Clearing an existing value uses ServiceStack's
resetinstruction where necessary. - Delete is shown only when an authorized Delete API exists and requires confirmation.
Server-side validation remains authoritative. Validation failures are returned as normal ServiceStack ResponseStatus field errors and displayed beside their inputs.
References and lookup controls​
[Ref], [References] and foreign-key metadata can render searchable lookup controls. Referenced schemas are loaded on demand from /auto/{ReferencedModel}.json, keeping the initial model schema small.
public class Booking
{
public int Id { get; set; }
[References(typeof(Customer))]
public int CustomerId { get; set; }
[Reference]
public Customer Customer { get; set; }
}
Authorization​
/auto is a client of the same APIs as any other UI. It does not bypass API authorization:
- The catalog omits models without an accessible Query API.
- A model schema omits write operations the caller cannot access.
- The API revalidates authentication, roles, permissions and validation rules when invoked.
- APIs excluded from metadata are not included.
The generated UI is therefore caller-specific, but the Service remains the final security boundary.
Customize generated controls​
The UI consumes the metadata already attached to Request DTOs and data models. Use the same attributes used by API Explorer and AutoQuery components:
public class CreateBooking : ICreateDb<Booking>, IReturn<IdResponse>
{
[Input(Type = "select", EvalAllowableValues = "['Single','Queen','Suite']")]
public RoomType RoomType { get; set; }
[ValidateGreaterThan(0)]
public decimal Cost { get; set; }
}
Useful metadata includes [Description], [Input], validation attributes, [Ref], [References], [Intl] and [Format].
To modify the generated envelope programmatically:
services.ConfigurePlugin<MetadataFeature>(feature => {
feature.OnAutoQuerySchema = (dataModel, schema) => {
if (dataModel == typeof(Booking))
schema["title"] = "Room Bookings";
};
});
Disable /auto​
The AutoQuery schema routes can be disabled without disabling /schema:
services.AddServiceStack(typeof(MyServices).Assembly, options => {
var metadata = options.Plugins.OfType<MetadataFeature>().First();
metadata.DisableAutoQuerySchema = true;
});
MetadataFeature.IsAutoQuerySchemaEnabled reports whether the routes are registered.
Embed the Vue component​
The built-in page uses the AutoQuerySchema component from @servicestack/vue. It can also be used in an application's own Vue UI:
<script setup>
import { ref, onMounted } from 'vue'
import { AutoQuerySchema } from '@servicestack/vue'
const schema = ref()
onMounted(async () => {
schema.value = await fetch('/auto/Booking.json').then(r => r.json())
})
</script>
<template>
<AutoQuerySchema v-if="schema" :schema="schema" />
</template>
Embed the React component​
The React package provides the equivalent AutoQuerySchema component. Pass it the model schema and a JsonServiceClient for the App serving the AutoQuery APIs:
import { useEffect, useMemo, useState } from 'react'
import { JsonServiceClient } from '@servicestack/client'
import { AutoQuerySchema } from '@servicestack/react'
export default function Bookings() {
const client = useMemo(() => new JsonServiceClient('/'), [])
const [schema, setSchema] = useState<any>()
useEffect(() => {
fetch('/auto/Booking.json', { credentials: 'include' })
.then(r => r.json())
.then(setSchema)
}, [])
return schema
? <AutoQuerySchema schema={schema} client={client} take={25} />
: null
}
Install the required packages with:
Related documentation​
- AutoQuery Schema overview - architecture, components and broader use cases
- API Schema - per-Request DTO schemas used by every CRUD operation
- AutoQuery RDBMS - defining Query and CRUD APIs
- Locode - standalone metadata-driven data management UI