|
| 1 | +--- |
| 2 | +title: Generate CRUD APIs and UIs from existing DBs |
| 3 | +--- |
| 4 | + |
| 5 | +A core piece of functionality in the [Text to Blazor CRUD App](/autoquery/text-to-blazor) feature is distilling an AI Prompt into TypeScript classes that can be [further customized](/autoquery/okai-models#customize-data-models) |
| 6 | +to generate AutoQuery CRUD APIs and Admin UIs for managing the underlying RDBMS tables. |
| 7 | + |
| 8 | +## TypeScript Data Models |
| 9 | + |
| 10 | +Using TypeScript is an effortless way to define data models, offering a DSL-like minimal boilerplate format that's human-friendly to read and write which can leverage TypeScript's powerful Type System is validated against the referenced [api.d.ts](https://okai.servicestack.com/api.d.ts) schema to provide a rich authoring experience |
| 11 | +with strong typing and intellisense - containing all the C# Types, interfaces, and attributes used in defining APIs, DTOs and Data Models. |
| 12 | + |
| 13 | +### Blueprint for Code Generation |
| 14 | + |
| 15 | +The TypeScript Data Models serve as the blueprint for generating everything needed to support the feature |
| 16 | +in your App, including the AutoQuery **CRUD APIs**, **Admin UIs** and **DB Migrations** that can re-create the necessary tables from scratch. |
| 17 | + |
| 18 | +## 1. Generate RDBMS Metadata |
| 19 | + |
| 20 | +The first step in generating TypeScript Data Models is to capture the metadata from the existing RDBMS tables which |
| 21 | +we can do with the `App.json` [AppTask](https://docs.servicestack.net/app-tasks) below which uses your App's configured |
| 22 | +RDBMS connection to generate the Table Definitions for all tables in the specified RDBMS connection and schema |
| 23 | +to the file of your choice (e.g `App_Data/App.json`): |
| 24 | + |
| 25 | +```csharp |
| 26 | +AppTasks.Register("App.json", args => |
| 27 | + appHost.VirtualFiles.WriteFile("App_Data/App.json",ClientConfig.ToSystemJson( |
| 28 | + migrator.DbFactory.GetTables(namedConnection:null, schema:null)))); |
| 29 | +``` |
| 30 | + |
| 31 | +This task can then be run from the command line with: |
| 32 | + |
| 33 | +:::sh |
| 34 | +dotnet run --AppTasks=App.json |
| 35 | +::: |
| 36 | + |
| 37 | +Which generates `App_Data/App.json` containing the table definition metadata for all tables in |
| 38 | +the specified RDBMS, e.g: |
| 39 | + |
| 40 | +```json |
| 41 | +[ |
| 42 | + { |
| 43 | + "name": "AspNetUserClaims", |
| 44 | + "columns": [ |
| 45 | + { |
| 46 | + "columnName": "Id", |
| 47 | + "columnOrdinal": 0, |
| 48 | + "columnSize": -1, |
| 49 | + "numericPrecision": 0, |
| 50 | + "numericScale": 0, |
| 51 | + "isUnique": true, |
| 52 | + "isKey": true, |
| 53 | + "baseCatalogName": "techstacks", |
| 54 | + "baseColumnName": "Id", |
| 55 | + "baseSchemaName": "public", |
| 56 | + "baseTableName": "AspNetUserClaims", |
| 57 | + "dataType": "System.Int32", |
| 58 | + "allowDBNull": false, |
| 59 | + "providerType": 9, |
| 60 | + "isAliased": false, |
| 61 | + "isExpression": false, |
| 62 | + "isAutoIncrement": true, |
| 63 | + "isRowVersion": false, |
| 64 | + "isHidden": false, |
| 65 | + "isLong": false, |
| 66 | + "isReadOnly": false, |
| 67 | + "dataTypeName": "integer", |
| 68 | + "columnDefinition": "INTEGER PRIMARY KEY AUTOINCREMENT" |
| 69 | + }, |
| 70 | + ], |
| 71 | + ... |
| 72 | +] |
| 73 | +``` |
| 74 | + |
| 75 | +### Different Connection or DB Schema |
| 76 | + |
| 77 | +If you prefer to generate the metadata for a different connection or schema, you can create a new AppTask |
| 78 | +with your preferred `namedConnection` and/or `schema`, e.g: |
| 79 | + |
| 80 | +```csharp |
| 81 | +AppTasks.Register("Sales.json", args => |
| 82 | + appHost.VirtualFiles.WriteFile("Sales.json", ClientConfig.ToSystemJson( |
| 83 | + migrator.DbFactory.GetTables(namedConnection:"reports",schema:"sales")))); |
| 84 | +``` |
| 85 | + |
| 86 | +That you could then generate with: |
| 87 | + |
| 88 | +:::sh |
| 89 | +dotnet run --AppTasks=Sales.json |
| 90 | +::: |
| 91 | + |
| 92 | +## 2. Generate TypeScript Data Models |
| 93 | + |
| 94 | +The next step is to generate TypeScript Data Models from the captured metadata which can be done with the `okai` tool |
| 95 | +by running the `convert` command with the path to the `App.json` JSON table definitions which will generate the |
| 96 | +TypeScript Data Models to stdout which can be redirected to a file in your **ServiceModel** project, e.g: |
| 97 | + |
| 98 | +:::sh |
| 99 | +npx okai convert App_Data/App.json > ../MyApp.ServiceModel/App.d.ts |
| 100 | +::: |
| 101 | + |
| 102 | +## 3. Generate CRUD APIs and Admin UIs |
| 103 | + |
| 104 | +The data models defined in the `App.d.ts` TypeScript Declaration file is what drives the generation of the Data Models, APIs, DB Migrations and Admin UIs. This can be further customized by editing the TypeScript Declaration file and re-running the `okai` tool with just the filename, e.g: |
| 105 | + |
| 106 | +:::sh |
| 107 | +npx okai App.d.ts |
| 108 | +::: |
| 109 | + |
| 110 | +Which will re-generate the Data Models, APIs, DB Migrations and Admin UIs based on the updated Data Models. |
| 111 | + |
| 112 | + |
| 113 | + |
| 114 | +:::tip |
| 115 | +You only need to specify the `App.d.ts` TypeScript filename (i.e. not the filepath) from |
| 116 | +anywhere within your .NET solution |
| 117 | +::: |
| 118 | + |
| 119 | +## Live Code Generation |
| 120 | + |
| 121 | +If you'd prefer to see the generated code in real-time you can add the `--watch` flag to watch the |
| 122 | +TypeScript Declaration file for changes and automatically re-generate the generated files on Save: |
| 123 | + |
| 124 | +:::sh |
| 125 | +npx okai App.d.ts --watch |
| 126 | +::: |
| 127 | + |
| 128 | +<video autoplay="autoplay" loop="loop" controls> |
| 129 | + <source src="https://media.servicestack.com/videos/okai-watch.mp4" type="video/mp4"> |
| 130 | +</video> |
0 commit comments