1. Project Overview & Quickstart (YaoApp/models)
Technical Documentation: YaoApp/models
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
models
Agent Skills & Rules
- Discovered 21 agent rule(s) and prompt configurations.
--- METRICS ---
- Files Extracted: 1
- Estimated Token Budget: ~24 tokens
- Canonical Reference: https://codewiki.google/github.com/YaoApp/models
2. Official Technical Reference & Guides (YaoApp/docs)
File: README.md
docs
Yao Official Documentation
File: blog/en-us/architecture/why-does-yao-reinvent-so-many-wheels.mdx
title: Why Does Yao Reinvent So Many Wheels?
published_at: 2024-12-04 00:00:00
cover: [/assets/images/blog-002.png]
authors:
- name: Max
avatar: [/assets/images/max.png]
In the field of software development, the phrase "Don't reinvent the wheel" is a well-known adage.
However, over the past three years, we have chosen a less-traveled path by "restructuring" several core aspects of web development. This has been a highly challenging endeavor, filled with unexpected difficulties and decisions.
Amidst support and skepticism, we persevered. Finally, in Yao's v0.10.4 release, we realized our initial vision:
A development tool that is "All-in-One";
A development tool that offers an excellent "development experience" for both humans and machines;
A development tool that meets the needs of most web development scenarios.
This is not just a new milestone but a rebirth for Yao.
The Origin
As a former Unix software engineer, I deeply experienced the efficiency bottlenecks when developing websites with C++ - from compiling to debugging, a lot of time was wasted on non-business development. Later, I switched to PHP, NodeJS, and other tech stacks, which indeed improved development efficiency. However, the separation of front-end and back-end brought new challenges: high communication costs within the team, sometimes leading to situations where "2 hours of development required 2 weeks of front-end and back-end communication."
This prompted me to think: Can we create a tool that allows developers to independently complete full-stack development in specific scenarios (such as websites, admin panels, and small to medium-sized business systems) while improving efficiency through code generation? This idea eventually gave birth to Yao - initially developed in PHP for internal use, later rewritten in Golang and open-sourced.
Why Reinvent the Wheel?
In fact, Yao does not reinvent the wheel but integrates and optimizes existing tech stacks. Its core philosophy is:
Simplify Dependencies - Streamline the tech stack, package core functions, and achieve true out-of-the-box usability. Say goodbye to dependency hell with no cumbersome configurations.
Full-Stack Componentization - Transfer the successful experience of front-end componentization to full-stack development, abstracting interactions, data, and logic into composable parts.
By doing so, Yao enables developers to handle both front-end and back-end with a unified development model and supports various web development scenarios through an extension mechanism. It retains mainstream tech stacks (Golang for the back-end, TypeScript + React/Vue for the front-end), essentially providing a more efficient development paradigm rather than reinventing the wheel.
Cursor Can Handle 90% of My Work, Why Use Yao?
Yao is based on mainstream tech stacks and offers a more efficient development paradigm. In fact, you can use Cursor to develop Yao applications. Currently, you only need to add a few prompts to help Cursor better understand Yao Runtime API and DSL. As large language models iterate and upgrade, these additional prompts will become fewer.
Yao's value lies not only in improving coding efficiency but also in optimizing team collaboration. By unifying the development paradigm, it significantly reduces communication costs and enhances overall team efficiency.
No Ecosystem, No Future
Yao adheres to the "human-machine-friendly" design philosophy, committed to providing simple and easy-to-use APIs and DSLs, allowing developers to get started quickly.
Newcomers might worry: Without a complete ecosystem, will having to implement all functions ourselves reduce development efficiency?
In reality, Yao not only comes with a rich set of Processes for common scenarios but also seamlessly integrates with two powerful ecosystems:
- Back-end Development: Directly use the Golang ecosystem, which offers excellent performance without additional learning.
- Front-end Development: Adopts the TypeScript + React/Vue ecosystem, allowing flexible component extension.
You can easily build private Processes and component libraries based on business needs, creating tailored solutions.
As outlined above, these are some answers to common questions and part of Yao's design philosophy. We believe that with Yao, you can build excellent web applications faster and enjoy the fun of development.
File: blog/en-us/releases/yao-v0.10.4-rc1.mdx
title: Yao 0.10.4-rc1 Release Notes published_at: 2024-12-04 00:00:00 cover: [/assets/images/blog-001.png]
The latest version of Yao, 0.10.4-rc1, is now available! This release introduces a host of new features, enhancements, and refinements, making Yao more powerful and user-friendly than ever.
🚀 New Features
🌟 AI Integration
Yao now provides comprehensive AI capabilities out of the box, making it easy to enhance your applications with artificial intelligence:
- OpenAI Integration: Built-in connector for OpenAI API with configurable models and settings
- Intelligent Chatbots: Add AI-powered chat interfaces to your applications with the Neo chatbot system
- AI-Enhanced Forms: Smart input fields with AI assistance for content generation and validation
- Content Generation: Generate text, descriptions, and other content dynamically using AI
- AI Agents: Create custom AI agents to automate tasks and enhance application workflows
- Developer-Friendly: Simple YAML configuration and TypeScript support for AI features
These AI capabilities are seamlessly integrated with Yao's existing features, allowing developers to add intelligence to their applications with minimal configuration.
For detailed examples and best practices, refer to our AI Integration Documentation.
🌟 Native Support for TypeScript
Yao now includes built-in TypeScript capabilities that enhance development efficiency and runtime performance:
- Built-in V8 Engine: Direct TypeScript execution without compilation steps
- Runtime APIs: Comprehensive API collection for database operations, file handling, and caching
- Type Definitions: Full TypeScript declarations for all Yao APIs and components
- Custom Scripts: Write backend logic in TypeScript with full IDE support
- Process Integration: Seamless TypeScript integration with Yao's process system
- Hot Reload: Automatic script reloading during development
- Extension Support: Multiple ways to extend functionality using TypeScript
TypeScript support is deeply integrated into Yao's core, providing modern development experience without additional setup.
For code examples and API documentation, visit our Yao Runtime.
🌟 SUI (Simple User Interface) Template Engine
Yao now features a powerful template engine for building dynamic web pages.
- Zero Build Tools: Create web pages instantly without complex build configurations
- Server-Side Rendering: Built-in SSR support for optimal performance and SEO
- Component System: Reusable components with HTML, CSS, and TypeScript
- File-Based Routing: Intuitive routing based on file system structure
- Data Integration: Simple data binding with
{{ variable }}syntax - TypeScript Support: Native TypeScript for both frontend and backend scripts
- Hot Reload: Built-in development tools with automatic page rebuilding
- AI-Friendly: Designed for seamless integration with AI-powered features
SUI makes web development straightforward while maintaining modern development practices and performance optimization.
For detailed tutorials and examples, check our Website Development Guide.
✨ Improvements
We've made several enhancements to Yao's core features and tools to provide a better development experience.
- Runtime - Fixed memory leaks and improved performance for TypeScript and JavaScript scripts
- Process System - Enhanced process management with improved error handling and logging
- Command Line Interface - Improved CLI with new commands and options for better usability
- Hightlighting and Autocompletion - Improved code editor support for TypeScript.
- Documentation - Updated documentation with new guides, examples, and best practices
- Bug Fixes - Fixed various issues reported by the community and internal testing
📚 Resources
Download Yao 0.10.4-rc1
Yao Official Website
The Yao official website demonstrates the Yao's capabilities in a production environment:
- Built with SUI: Showcases real-world usage of the SUI template engine
- AI-Powered: Features AI-enhanced chatbots and content generation
- Open Source: Available as a reference implementation on GitHub under the MIT license
- Performance: Demonstrates SSR capabilities and SEO optimization
- Multilingual: Supports multiple languages with dynamic content switching
Explore the source code at github.com/YaoApp/website to learn best practices and implementation patterns.
Yao Playground
The Yao Playground, launching with v0.10.4-rc2, will demonstrate how to create complete web applications through natural language conversations with an AI assistant.
File: documentation/en-us/README.md
Yao Official Documentation
File: documentation/en-us/01-getting-started/01-switching-to-yao.mdx
title: Switching to Yao
Switching to Yao is easy. Yao focuses on generative programming. It may take time to learn a few key concepts, but once you understand them, you’ll see that Yao is a powerful tool. It helps you build applications faster and offers a great development experience.
The following sections will help you understand the core concepts of Yao and how to use them to build applications.
Generative Programming
Before the AGI era, we believe the best way to work with AI is as a collaborator, not a master.
We aim to make generated code match hand-written code, easy to read and modify, so developers and machines can collaborate seamlessly.
- For Human: We want the code to be easy to read and write, clear, and intuitive.
- For Machine: We aim to make the code AI-friendly, easy to generate, and simple to extend.
In Yao, we use a DSL (Domain-Specific Language) to describe widgets, assemble them into applications, and use processes for atomic functions.
Yao widget could be a Table, Form, List, or Chart. It could also be a Data Model, API, Store, Flow, etc.
Yao DSL is an intermediate language understandable by both humans and machines. It can be generated by AI, created via GUI, or written manually, with seamless switching between approaches.
Use the Yao runtime to execute the code, and its built-in HTTP server to serve the application.
Yao Application
A Yao application is a collection of widget DSLs and custom processes written in TypeScript or JavaScript.
For websites, the SUI template engine (new in version 0.10.4) can help you build the web pages you need.
Each widget type has its own directory in the project root, such as models, tables, forms, apis, etc.
The DSL source files are named in lowercase with the .[TYPE].yao extension, for example, article.mod.yao.
Custom process files are lowercase in the scripts directory, e.g., article.ts. The process name is scripts.article.[FUNCTION_NAME].
Directory Structure
The yao application directory structure is as follows:
app
├── aigcs # AIGC Widgets: use the prompt as a process
├── apis # API Widgets: define the REST API
├── app.yao # Application Configuration
├── charts # Chart Widgets: chart-type pages in the admin panel
├── connectors # AI Connectors, Database Connectors, Redis Connectors, etc.
├── dashboards # Dashboard Widgets: dashboard-type pages in the admin panel
├── data # The default application data directory, use the File System Process or JSAPI to access. Custom data directory can be set in environment variables.
├── db # The sqlite database directory, the default option of database. If use another database, this directory is not necessary.
├── flows # Flow Widgets: define the process flow
├── forms # Form Widgets: form-type pages in the admin panel
├── icons # The application icons used in the admin panel
├── langs # I18n language files used in the admin panel
├── logins # Login Widgets: login-type pages in the admin panel
├── logs # The application log directory, the default option of log. Custom log directory can be set in environment variables.
├── models # Model Widgets: define the data structure
├── neo # The AI Chatbot configuration directory
├── plugins # The Default GRPC plugins directory, Custom plugins directory can be set in environment variables.
├── public # The static files directory, can be accessed via the HTTP server. SUI template engine generates the web pages here too.
├── scripts # Custom Process: write the custom process in TypeScript or JavaScript
├── tables # Table Widgets: table-type pages in the admin panel
└── .... # Other widget types, or your self-defined widget typesHow to develop a Yao application?
There are three things you need to do to develop a Yao application:
- Write DSL: Describe the widget in DSL, such as Model, API, Table, Form, etc.
- Write Process: Write the custom process in TypeScript or JavaScript, or use write GRPC plugins.
- Debug and Run: Use the Yao runtime to debug and run the application.
yao start is the command to start the application server. In development mode, Yao watches changes to the DSL and Process files and automatically reloads the application server.
yao run is the command to run a process. You can use it to test the process before integrating it into the application.
Visual Studio Code is the recommended IDE for developing Yao applications. set the .yao file type to jsonc in the settings, you can get the syntax highlighting and auto-completion.
For more information, see:
Tips for switching to Yao
Yao is a new way of building web applications. Here are some tips to help you switch to Yao.
1. The Best Way to Learn: Practice and Read Source Code
The best way to learn is through hands-on practice. Follow the documentation to build a simple application and explore the basics.
You can also read the application source code, to see how the widgets are described and how the processes are written.
Here ase some repositories you can refer to:
2. Planning Before Starting Development
In Yao, the data model is crucial. When beginning development, it's essential to plan the data structure and relationships.
When starting a new project, define the data model in the models directory first. Then, create the Table, Form, and API widgets based on this model.
Preparing test data and creating an import process is a good practice, as it enhances development efficiency. When deploying the application, you can use this process to import demo data.
You can generate test data using AI by sending the Model DSL to the AI and asking it to generate the data.
3. AI Generation First, Then Manual Modification
The fastest way to create a widget is by using AI to generate the DSL, which you can then manually tweak to fit your needs.
For example:
- Provide a Model DSL to the AI, specify your requirements, and let the AI generate a similar one. You can then adjust it as needed.
- You can also provide both a Model DSL and a Table DSL to the AI, allowing it to generate a Table widget DSL that binds to the Model. Adjust it as necessary.
The Yao Playground repository offers a simple tool for generating DSLs, which you can use. Alternatively, you can develop your own tool for this purpose.
4. Suggestions for Frontend Developers
Before starting development, it's helpful to have some backend knowledge:
- Understand database structures and relationships.
- Grasp the basics of REST APIs and their functionality.
- Know TypeScript or JavaScript for writing server-side custom processes.
Follow the documentation to build a simple application. Learn how to create Models, write custom processes, and develop REST APIs.
5. Suggestions for Backend Developers
Before starting development, some frontend knowledge is helpful:
- TypeScript or JavaScript is crucial for writing custom processes. TypeScript is recommended.
- Basic understanding of HTML, CSS, and JavaScript is essential for building websites.
Creating an admin panel in Yao is straightforward, no frontend coding required. Use Table, Form, and API widgets to build it. It's like crafting an HTML page, but more powerful, using DSL to describe the page and processes to handle data.
Follow the documentation to build a simple application and learn to use these widgets for an admin panel.
Limitations of Yao
Although we have mentioned that Yao can handle everything for web development, there are still some things that may not be the best fit for Yao.
Highly Customized UI: If you need a highly customized UI for an admin panel or enterprise app, you might have to write custom code. However, you can utilize Yao as a backend service. 👉 Building your component library
Mobile App Client: For a mobile app client, you may need to develop a native app or use a mobile app development framework, while using the Yao as a backend service. 👉 REST API
The SUI template engine, introduced in Yao 0.10.4, offers a fresh way to build web pages. It's still experimental and not fully developed, but it provides a new option for developers. For more advanced frontend needs, consider using frameworks like React or Vue and connect them to Yao via REST API. 👉 Web Page
TypeScript is the recommended language for writing custom processes, it will be run in the V8 engine. If high-performance is nessary, add the process in Go, it's faster than TypeScript. 👉 Adding your process
Concepts Explained
Yao Process
A Process in Yao is an atomic function that runs in the Yao Runtime.
Yao provides hundreds of internal processes with diverse functionalities. You can also create custom processes in TypeScript or JavaScript.
- Internal Process: Defined in Yao's source code, you can find them in the Yao respository.
- Custom Process: Written in TypeScript or JavaScript, located in the
scriptsdirectory of your project. - GRPC Plugin: Written in any language, located in the
pluginsdirectory of your project.
To run a process, use the yao run command.
For more information, see: 👉 Process References
Examples:
# Execute an internal process
yao run utils.app.Ping # This will return the version of Yao.
# Execute a custom process defined using TypeScript
yao run scripts.test.Hello 'Yao!' # Returns 'Hello, Yao!'
yao run scripts.test.Pets cat # Returns a list of pets in the cat category.scripts/test.ts
import { Process } from "@yao/runtime";
function Hello(name: string): string {
return `Hello, ${name}!`;
}
function Pets(category?: string): Record<string, any> {
category = category || "dog";
const pets = Process("models.tests.pet.Get", {
select: ["id", "name"],
wheres: [{ column: "category", value: category }],
});
return pets;
}Yao Runtime
Yao Runtime is a server-side execution environment for running processes.
- Internal Processes written in Go, executed directly.
- Custom Processes written in TypeScript or JavaScript, executed using the V8 engine. Yao provides APIs like
Process,File System, andHTTP Requestto write these processes.
Note: Yao Runtime is not Node.js. It's specifically for running processes and does not support Node.js APIs.
Execution Methods:
- CLI: Use the
yao runcommand. - HTTP Server: Use the built-in HTTP server to run processes via REST API.
Yao Widget
A Widget in Yao is not just a traditional frontend component; it is a combination of UI, interaction, logic, and data. There are no frontend and backend concepts in a Widget; it is a self-contained unit.
A widget could be a Table, Form, List, or Chart. It could also be a Data Model, API, Store, Flow, etc.
Each Widget has a set of Processes, and some Widgets have a set of REST APIs. It can be used in other widgets, custom processes, or integrated into other applications.
A Widget is described using DSL, which is in JSON format. It can be generated by AI, created via a GUI, or written manually.
For more information, see: 👉 DSL References
Model Widget
Model Widget is used to describe the data structure, it same as the database table schema.
The Model DSL contains a set of processes to operate on the data, such as CRUD, Query, etc. You can use it directly.
// Model DSL
{
"name": "Article",
"table": { "name": "article", "comment": "Article" },
"columns": [
{ "name": "id", "comment": "ID", "type": "ID", "label": "ID" },
{ "label": "Title", "name": "title", "type": "string" },
{ "label": "Summary", "name": "summary", "type": "string" }
]
}# Use the process to find the data
yao run models.article.Find 1 '::{}'Table Widget
Table Widget is used to display the data in a admin panel. bind to the Model Widget, automatically generate the basic CRUD operations.
The Table DSL contains a set of processes and REST APIs to operate on the data, such as Find, Search etc. You can use it directly.
// Table DSL
{
"name": "Articles",
"action": {
"bind": { "model": "article", "option": { "form": "article" } }
}
}# Use the process to search the data
yao run yao.tables.Search article '::{}' 1 10# Use the REST API to search the data
curl --request GET \
--url https://127.0.0.1:5099/api/__yao/table/article/search \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer your_token_here'License Overview
Yao is available under two distinct licenses to accommodate various user needs: the Apache 2.0 License and the Yao Commercial License.
Apache 2.0 License
Under the Apache 2.0 License, you are free to use, modify, and distribute Yao. This open approach encourages integration and innovation, with the simple requirement that the original copyright notice and license terms be included in any distribution.
Yao Commercial License
To ensure we can sustain and enhance Yao's development, we are introducing the Yao Commercial License. This license supports our future offerings such as application hosting and AI web application generation services. It is essential for specific commercial uses that go beyond the scope of the Apache 2.0 License.
While the Apache 2.0 License covers most commercial applications, a commercial license is necessary for:
- Application Hosting Services
- AI Web Application Generation Services
We value your understanding and support as we work to improve Yao for the entire community. By respecting these licensing terms, you help us allocate more resources to develop and maintain Yao, ensuring it remains a robust tool for everyone.
File: documentation/en-us/01-getting-started/02-installation.mdx
title: Installation
related:
title: Next Steps
links:
- building-your-application
Yao is a standalone executable with no dependencies on packages or toolchains. Simply download and run it to begin building your application. You only need one installation per machine or server.
Installing
Run the following command to install Yao on your machine or server.
Linux and macOS
curl -fsSL https://yaoapps.com/install.sh | bashWindows
To install Yao on Windows, you need to have WSL2 installed. If you don't have WSL2 installed, you can follow the official guide.
powershell -c "irm yaoapps.com/install.ps1 | iex"Docker
Yao provides production and development Docker images that support x64 and arm64 architectures.
The development image includes additional tools and libraries for development and is based on Ubuntu 22.04, while the production image is smaller and based on Alpine 3.14.
Download the latest production image:
docker pull yaoapp/yao:latest
# or specify the version
docker pull yaoapp/yao:0.10.4-rc.1Download the latest development image:
docker pull yaoapp/yao:latest-dev
# or specify the version
docker pull yaoapp/yao:0.10.4-rc.1-devChecking the Installation
After installing Yao, you can check the version by running the following command:
yao version --allIf an error occurs, please verify that the yao command is in your system’s PATH.
If it’s not found, you may need to add the directory containing the yao executable to your PATH and ensure it has execute permissions.
Download the development version
Yao is under active development, and you can download the latest development version to try out new features and improvements.
For Windows, you can download the Linux version and run it in WSL2.
Linux Artifacts
👉 https://github.com/YaoApp/yao/actions/workflows/build-linux.yml
On the above page, select the latest build, download and unzip it, then choose the artifact file for your CPU architecture. Supported architectures are x64 and arm64.
MacOS Artifacts
👉 https://github.com/YaoApp/yao/actions/workflows/build-macos.yml
On the above page, select the latest build, download and unzip it, then choose the artifact file for your CPU architecture. Supported architectures are Intel CPU and M1/M2/M3/M4 (arm64)
File: documentation/en-us/01-getting-started/03-why-yao.mdx
title: Why Yao?
AI is transforming the world, especially in web development. Today, AI isn't just a luxury—it's essential. It helps create better products, make smarter decisions, and boost your business.
AI can understand language, write code, and even outperform humans in some areas, but it still requires expertise to master.
We're dedicated to making human-machine collaboration in web development easier and more efficient, which is why we created Yao.
The Journey of Exploration
In February 2022, we launched the first public version of Yao, aiming for developers to adopt it as an innovative tool for building web applications, demonstrating that it can be used directly to create them.
By November 2022, we released an updated version of Yao, featuring a demo app that auto-generates code using another program. This demonstrated that machines can generate code, while humans can comprehend and refine it.
Fortunately, Yao was recognized by some developers, coinciding with the release of the groundbreaking GPT-3.5 model at the end of the same year. This validation confirmed we were on the right path, motivating us to continue refining Yao.
After two years of development, Yao has matured into a stable tool that seamlessly integrates human and AI collaboration, delivering an excellent development experience.
Yao offers enhanced capabilities in web development, and we are eager to see more developers using it to create web applications.
Features
Yao is effective in both human and machine programming, with each being independent, allowing for seamless switching between the two.
🔮 AI First
We have designed a human-machine-friendly DSL (Domain-Specific Language) that makes both AI-generated and manually written code more efficient, enabling easy transitions between the two.
Typically, AI generates the initial code, and developers make modifications, significantly boosting development efficiency. In practice, AI can handle 80% to 90% of the work, allowing developers to focus on the remaining 10% to 20%.
🔮 All-in-One
Yao is an all-in-one solution for web development, requiring no additional packages or toolchain dependencies. It ships as a single executable file that includes everything you need to get started.
This greatly reduces the complexity of interacting with AI, significantly improving both the efficiency and quality of the generated code. It also eliminates many unnecessary tasks, allowing developers to focus on more important aspects.
🔮 Native TypeScript Support
Yao includes a built-in V8 engine with TypeScript support, allowing direct code execution and providing hundreds of APIs for databases, files, caching, and more, with multiple ways to add extensions.
Yao offers comprehensive programming capabilities, so you don’t have to worry about being unable to implement certain features.
🔮 Multiple Coding Approaches
Combine AI-generated code, visual editing, and manual coding within the same project, with generated code that is easy to read and manually modify.
Once you understand how Yao works and its DSL, you can easily develop a code generator or AI agent tailored to your business needs.
🔮 Serverless
Launch in seconds with built-in cloud functions and API gateways to easily create server-side apps. Integrate seamlessly with the DevOps ecosystem for one-click deployment.
🔮 Edge Devices Support
Yao apps also support running on edge devices equipped with arm64 or x64 chips, suitable for various scenarios in IoT applications.
File: documentation/en-us/01-getting-started/index.mdx
title: Getting Started
Welcome to the Yao documentation!
What is Yao?
Yao is an all-in-one application engine that enables developers to create web apps, REST APIs, business applications, and more, with AI as a development partner.
Generative Programming
Generative Programming is the core concept of Yao. It means that you can generate code using AI, GUI, or by writing code. The Yao DSL is designed to be human-readable, easy to write, AI-friendly, and easily extendable.
All-in-one App Engine
Yao has a built-in suite of tools essential for application development, such as:
- TS/JS/DSL Runtime: A runtime that can directly run TypeScript, JavaScript, and DSL code.
- HTTP Server: A powerful HTTP server that can handle any HTTP request, for REST APIs, web pages, etc.
- Process Engine: Hundreds of processes that cover the needs of over 90% of applications.
- UI Components: UI components that support AI-powered inputs and can be used in DSL code with simple syntax to build dashboards, admin panels, and more.
- Template Engine: A component-based template engine that can generate any web page.
- AI Connector: A connector that integrates AI models for use within your application.
- Database: A powerful ORM for database interactions.s
- File System: File system operations that can be used in your application.
More features can be found in the Why Yao document.
All these features are packaged into a single executable with no package or toolchain dependencies. Just download and run it to start building your application.
Yao can bring you a whole new development experience, increasing your development efficiency by several times.
Quickstart
To get started with Yao, follow these steps:
Step 1: Install Yao
Follow the Installation guide to install Yao on your machine or server. You only need one installation per machine or server.
Linux and macOS:
curl -fsSL https://yaoapps.com/install.sh | bashWindows (WSL2 Required):
powershell -c "irm yaoapps.com/install.ps1 | iex"Step 2: Create a New Project
Create a new project: Run the following command to create a new project:
# Create an empty directory for your project
mkdir /path/to/your/project
# Enter the project directory
cd /path/to/your/project
# use yao start command to start application server
# Use `Ctrl + C` to stop the server.
yao startThe first time run yao start in an empty directory, Yao will create a new project in the current directory.
Open the browser and visit http://127.0.0.1:5099 to see the default web page.
(Replace the IP address and port with yours)
Step 3: Run a Process to See How Yao Works
Process is a core concept in Yao. It represents a function that can be run directly or referenced in your code.
Yao includes many internal processes that meet the needs of over 90% of applications.
You can also define your own processes using TypeScript, GRPC plugins, or other methods.
Open a new terminal, enter the project directory, and run the following commands:
#
# Run internal processes
#
# Use the utils.* process to run a utility process.
# The process is defined in Yao’s source code.
# You can find it in the Yao project at the following link:
# https://github.com/YaoApp/yao/blob/840dae4b163811347598c740f43d43be065d01fa/engine/process.go#L30
#
yao run utils.app.Ping # This will return the version of Yao.
# Use the models.* process to query the database.
# The Model DSL is defined in the models/tests/pet.mod.yao file within your project directory.
# The first argument is the ID of the pet, and the second argument is the query.
# If the argument is an object, use the '::' prefix to pass the object as a string.
yao run models.tests.pet.Find 1 '::{}' # Returns all fields of the pet.
yao run models.tests.pet.Find 1 '::{"select": ["id", "name"]}' # Returns only the id and name of the pet.
#
# Run a process defined using TypeScript
#
# Use the scripts.* process to run a TypeScript process.
# The TypeScript process is defined in the scripts/tests/hello.ts file within your project directory.
# Command-line arguments will be passed to the TypeScript function as parameters.
yao run scripts.tests.Hello 'Hello, Yao!' # Returns 'Hello, Yao!'How to Read the Documentation
There are three types of documents in the Yao documentation:
- Documentation These documents provide an overview of Yao’s features and concepts.
- Tutorials These documents provide step-by-step instructions for building applications with Yao.
- References These documents provide detailed information about Yao DSL, processes, JSAPI, and more.
Documentation
On the left side of the screen, you can find the navigation menu. The docs are organized sequentially, from basic to advanced. You can read them in order to get a better understanding of Yao.
Practice is the best way to learn. We recommend that you follow the documentation and try to build a simple application to get started.
Tutorials
The tutorials are organized by scenario, such as building a website, REST API, admin panel, business app, etc.
You can find the tutorials in the Uses section of the website. Each tutorial provides step-by-step instructions for building an application.
👉 Uses
Choose a tutorial based on your needs:
| Tutorial | Description | Link |
|---|---|---|
| Website | A tutorial for building a website. (in progress) | 👉 Website |
| REST API | A tutorial for building a REST API. (in progress) | 👉 REST API |
| Admin Panel | A tutorial for building an admin panel. (in progress) | 👉 Admin Panel |
| Command-Line Tool | A tutorial for building a Command-Line Tool. (in progress) | 👉 Command-Line Tool |
| Business Application | A tutorial for building an business application. (in progress) | 👉 Business Application |
| Edge Application | A tutorial for building an application deployed on edge devices. (in progress) | 👉 Edge Application |
References
The references provide detailed information about Yao DSL, processes, JSAPI, and more. You can find the references at the end of the navigation menu.
| Reference | Description | Link |
|---|---|---|
| Yao Command | A complete list of all commands available in the Yao CLI, along with their descriptions. | 👉 Yao Command |
| Yao Process | A detailed list of all Yao internal processes and their descriptions. | 👉 Yao Processes |
| Yao Runtime | A complete list of all Yao runtime APIs along with their descriptions. | 👉 Yao Runtime |
| Yao DSL | A complete list of all Yao Widget DSLs and their descriptions. | 👉 Yao DSL |
| Query DSL | A detailed list of all database Query DSLs with their descriptions. | 👉 Query DSL |
| UI Components | A complete list of all UI components in Yao DSL with their descriptions. | 👉 UI Components |
| Template Engine | A detailed list of all template engine APIs with their descriptions. | 👉 Template Engine |
File: documentation/en-us/02-building-your-application/01-yao-command.mdx
title: Yao Command
related:
title: Next Steps
links:
- debug-guide
Yao is a standalone executable. You only need one installation per machine or server, even if you have several projects.
This section introduces basic Yao command, which will be used later to build a simple application. A quick glance will suffice.
For more detailed information, see the Yao command references.
Overview
Basic usage of the Yao command:
| Command | Description | Example |
|---|---|---|
yao start |
Start the application server | yao start |
yao run |
Run a process | yao run utils.app.Ping |
yao migrate |
Migrate the database, build the schema | yao migrate |
yao version |
Display the version of Yao | yao version --all |
SUI Command, for web page building:
| Command | Description | Example |
|---|---|---|
yao sui build |
Build the SUI page | yao sui build web default |
yao sui watch |
Watch the SUI page changes, and rebuild automatically | yao sui watch web default |
File: documentation/en-us/02-building-your-application/02-debug-guide.mdx
[Binary file]
File: documentation/en-us/02-building-your-application/03-data-model.mdx
title: Data Model
related:
title: Next Steps
links:
- rest-api
Starting from this section, we'll build a simple pet store application together, demonstrating how to use Yao effectively. You will learn how to:
- 🟠 Create and manage data in your application.
- ⚪ Develop RESTful APIs to expose data. 👉 REST API
- ⚪ Design web pages to display data. 👉 Web Page
- ⚪ Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
Ensure you have read the previous documentation, to understand the basic concepts of Yao.
Overview
Data models are blueprints for defining the structure of your data and are the most important part of a Yao application.
In Yao, the Data Model is a widget that uses Model DSL to describe your data's structure, similar to a database schema. Understanding database structures and relationships will help you design your data model effectively.
The data will be stored in a database. By default, Yao uses SQLite as the database engine. You can change the database engine to MySQL or other databases by modifying the environment configuration. 👉 App Configuration
For more details about Model DSL, see 👉 DSL References
Step 1: Plan Your Data Structure
Before creating a data model, you should plan the structure of your data. The best way is to let an AI chatbot assist you.
Open an AI Chatbot and ask for help to generate data structure for your application.
💬 Prompts for planning data structure
This is an example of a conversation with an AI chatbot to plan the data structure for a pet store application. Change the prompts according to your requirements.
- I want to create a pet store application.
- The functionality includes adding, updating, and deleting pets, pet's categories and goods in the store.
- Help me design the data structure, Please provide me with a list of data tables and their fields.
- Reply to me with the table name, field name, and field type for each table.
- Table and field names should be in snake_case, Auto-increment fields should be named as `id`, wrapped in code blocks.
- For example:
```plaintext
Table: pet_categories
- id: INT PRIMARY KEY AUTO_INCREMENT
- category_name: VARCHAR(255) NOT NULL
- description: TEXT
```🤖 _Reply from AI Chatbot_
Table: pet_categories
- id: INT PRIMARY KEY AUTO_INCREMENT
- category_name: VARCHAR(255) NOT NULL
- description: TEXT
Table: pets
- id: INT PRIMARY KEY AUTO_INCREMENT
- pet_name: VARCHAR(255) NOT NULL
- category_id: INT NOT NULL
- age: INT
- breed: VARCHAR(255)
- description: TEXT
- FOREIGN KEY (category_id) REFERENCES pet_categories(id)
Table: goods
- id: INT PRIMARY KEY AUTO_INCREMENT
- good_name: VARCHAR(255) NOT NULL
- category_id: INT NOT NULL
- price: DECIMAL(10, 2) NOT NULL
- stock_quantity: INT NOT NULL
- description: TEXT
- FOREIGN KEY (category_id) REFERENCES pet_categories(id)
Table: transactions
- id: INT PRIMARY KEY AUTO_INCREMENT
- pet_id: INT
- good_id: INT
- transaction_date: DATETIME NOT NULL
- quantity: INT NOT NULL
- total_price: DECIMAL(10, 2) NOT NULL
- FOREIGN KEY (pet_id) REFERENCES pets(id)
- FOREIGN KEY (good_id) REFERENCES goods(id)
Explanation:
pet_categories: This table stores the various categories of pets and goods available in the store.
pets: This table keeps track of the pets available in the store, including their name, age, breed, and category.
goods: This table records the goods available for purchase, including their name, price, stock quantity, and associated category.
transactions: This table logs transactions involving pets and goods, including the date, quantity, and total price.Step 2: Generate Model DSL
With your data structure planned, you can now generate the Model DSL for your application.
Send your data structure and one or more existing Model DSL examples to the chatbot, and ask for help in generating similar Model DSLs.
You can get the existing Model DSL examples from the Yao documentation or other public repositories. in this case, we will use the article model from the Yao website repository.
💬 Prompts for Generating Model DSL
This is an example of a conversation with an AI chatbot to generate Model DSL for a pet store application. Change the prompts according to your requirements.
Model DSL Samples:
[Model DSL Samples]
Structure Planned:
[Structure Planned (The response from the AI chatbot in the previous step)]
- According to the planned structure, I need help generating Model DSL for the pet store application.
- Please provide me the Model DSL like the example provided.
- Each Model DSL should be wrapped in a code block.🤖 _Reply from AI Chatbot_
The AI chatbot will generate the Model DSL for each table based on the provided structure.
It looks like this:
// Model DSL for pet_categories
{
"name": "PetCategory",
"table": { "name": "pet_categories", "comment": "Pet Categories" },
"columns": [
{ "name": "id", "comment": "ID", "type": "ID", "label": "ID" },
{
"label": "Category Name",
"name": "category_name",
"comment": "Name of the pet category",
"type": "string",
"length": 255,
"nullable": false
},
{
"label": "Description",
"name": "description",
"comment": "Description of the pet category",
"type": "text",
"nullable": true
}
],
"option": { "timestamps": true }
}
// ....📝 Notes:
You can improve the prompts and Generate Model DSL directly. In this example, steps are separated for better understanding.
💬 Prompts for Generating Model DSL Directly
Following the next prompts, you can generate Model DSL directly.
Model DSL Samples:
[Model DSL Samples]
- I want to create a pet store application.
- The functionality includes adding, updating, and deleting pets, pet's categories and goods in the store.
- Help me design the data structure for the pet store application.
- According to the planned structure, I need help generating Model DSL for the pet store application.
- Please provide me the Model DSL like the example provided.
- Each Model DSL should be wrapped in a code block.🪄 Add More Promts
Adding more prompts helps generate better Model DSLs. The more information you provide, the better the AI chatbot can understand your needs.
For example, describe your business to the AI chatbot, and it will generate more tailored Model DSLs for you.
You can also establish some coding standards to facilitate future development and maintenance work.
Step 3: Save Model DSLs
Before proceeding, ensure you've reviewed the previous documentation to understand the Yao application's directory structure and have created a Yao application using the Quick Start Guide.
💾 Save to Models Directory
After generating the Model DSLs, save only the JSON partials in the models directory of your Yao application. Ensure the file and directory names are in lowercase and have a .mod.yao extension. You can further organize them using subdirectories.
For example:
- Save the
petsModel DSL asmodels/pets.mod.yao, with a widget ID ofpets. - Save the
pet_categoriesModel DSL asmodels/pet/categories.mod.yao, with a widget ID ofpet.categories.
The Widget ID is crucial for process references, replacing the / with a .. for example, models.pet.Find or models.pet.categories.Find.
After saving, the models directory should look like this:
└── models
├── goods.mod.yao
├── pet
│ └── categories.mod.yao
├── pets.mod.yao
└── transactions.mod.yaoYou can find them in the Demo Application repository. 👉 Demo Application
📝 Notes:
For maintaining the Model DSLs, it recommended keeping the Model DSLs names consistent with the table names. This will help you easily identify the Model DSLs for each table.
The table name defined in the Model DSL. table names should be in snake_case, as should field names, and both must be all lowercase. This is a strict requirement in Yao to ensure cross-platform file system compatibility.
For example:
{
"name": "Pet Categories",
// The table name is the name of the table in the database
"table": { "name": "pet_categories", "comment": "Pet Categories" },
"columns": [{ "name": "id", "comment": "ID", "type": "ID", "label": "ID" }]
}- the
pet_categoriestable saved atmodels/pet/categories.mod.yaowill have a widget ID ofpet.categories. - the
petstable saved atmodels/pets.mod.yaowill have a widget ID ofpets.
Step 4: Create Database Tables
Once you've saved the Model DSLs, you can create the database tables based on the Model DSLs using the yao migrate command.
📺 Yao Migrate Command
Enter the project root directory and run the yao migrate command. This will create the database tables based on the Model DSLs located in the models directory.
If you've already done this and need to reset the database, you can run yao migrate with the --reset flag.
yao migrate command is intended for development and testing environments only. If you need to use it in a production environment, you must include the --force flag to execute it. This is a dangerous operation, so proceed with caution.
You can switch between development and production modes by setting the YAO_ENV environment variable. For more details, refer to the 👉 App configuration
# Enter the project root directory,
# If multiple projects in your machine, ensure you are in the correct project directory.
cd /path/to/your/project
# Migration all models at once
# Create database tables based on Model DSLs. if the tables already exist, it will be altered.
yao migrate
# Migration all models at once with the --reset flag
# Reset the database tables. This will drop the existing tables and recreate them.
yao migrate --reset
# Migration one model at a time
# Create database table based on the Model DSL of a specific model.
# The argument is the widget ID of the model. eg: pets, pet.categories
yao migrate --name pets
# Migration one model at a time with the --reset flag
# Reset the database table of a specific model.
# The argument is the widget ID of the model. eg: pets, pet.categories
yao migrate --name pets --reset
# For production environment, use the --force flag.
yao migrate --forceAfter running the yao migrate command, check the results in the terminal.
AI can occasionally make mistakes, If there are any errors, report them to the AI chatbot for help, update the Model DSLs as needed, and repeat until successful.
The correct output should look like this:
Update schema model: goods (goods) SUCCESS
Update schema model: pet.categories (pet_categories) SUCCESS
Update schema model: pets (pets) SUCCESS
Update schema model: transactions (transactions) SUCCESS✅ Check the Database Tables
In this case, the sqlite database file will be created in the db directory of your Yao application after successfully running.
If you want to use a different database engine, you can modify the environment configuration. 👉 App configuration
You can use a database management tool to check the database tables, such as DB Browser for SQLite, DBeaver, or any other tool you prefer.
Step 5: Prepare Test Data (Optional)
Preparing test data and setting up a custom process for importing it is a good practice to enhance development efficiency.
After creating the database tables, you can generate test data for each table based on the Model DSLs.
Send the Model DSLs to an AI chatbot and ask for help in generating test data for each table. Then, use the yao run command to execute the models.* internal processes to import the test data.
💬 Prompts for Generating Test Data
This is an example of a conversation with an AI chatbot to generate Model DSL for a pet store application. Change the prompts according to your requirements.
Model DSLs:
[Model DSLs]
- I have created the database tables based on the Model DSLs.
- I need help generating test data for each table.
- Please provide me with the test data for each table.
- I will use the **yao run** command to import the test data.
- The command is **yao run models.<WIDGET_ID>.Insert '::["field_name_1","field_name_2",...]' '::[[field_1_value, field_2_value, ...],[field_1_value, field_2_value, ...]]'**.
- The "::" is used to pass the JSON string as an argument.
- The WIDGET_ID is the widget ID of the model. it's named from the Table name in the Model DSL. table name pet_categories with widget ID pet.categories table name pets with widget ID pets
- DO NOT INCLUDE the ID field in the test data.
- BE CAREFUL the FOREIGN KEY fields SHOULD be valid.
- EACH TABLE SHOULD have at least 3 records.🤖 _Reply from AI Chatbot_
The AI chatbot will generate the test data, and the reply will look like this:
# Pet Categories
yao run models.pet.categories.Insert '::["category_name","description"]' '::[
["Dogs", "Domesticated carnivorous mammals that typically have a long snout and barking voice."],
["Cats", "Small domesticated carnivorous mammals with soft fur and retractable claws."],
["Birds", "Warm-blooded egg-laying vertebrates characterized by feathers and wings."]
]'
# pets
yao run models.pets.Insert '::["pet_name","category_id","age","breed","description"]' '::[
["Buddy", 1, 3, "Golden Retriever", "Friendly and energetic dog."],
["Whiskers", 2, 2, "Siamese", "Curious and playful cat."],
["Tweety", 3, 1, "Canary", "Bright yellow songbird."]
]'
# ....📺 Import Test Data
After generating the test data, you can use the yao run command to import the test data into the database tables.
yao run command is used to execute a single process. This is useful for debugging custom processes.You can find how to use it in the 👉 Debug Guide
Copy the generated yao run commands and paste them into the terminal to execute.
# Enter the project root directory,
# If multiple projects in your machine, ensure you are in the correct project directory.
cd /path/to/your/project
# Run the yao run command to import the test data
yao run models.pets.Insert '::["pet_name","category_id","age","breed","description"]' '::[
["Buddy", 1, 3, "Golden Retriever", "Friendly and energetic dog."],
["Whiskers", 2, 2, "Siamese", "Curious and playful cat."],
["Tweety", 3, 1, "Canary", "Bright yellow songbird."]
]'
# ....The correct output should look like this:
Run: models.pet.categories.Insert
args[0]: ["category_name","description"]
args[1]: [
["Dogs", "Domesticated carnivorous mammals that typically have a long snout and barking voice."],
["Cats", "Small domesticated carnivorous mammals with soft fur and retractable claws."],
["Birds", "Warm-blooded egg-laying vertebrates characterized by feathers and wings."]
]
--------------------------------------
models.pet.categories.Insert Response
--------------------------------------
null
--------------------------------------
✨DONE✨if there are any errors, report them to the AI chatbot for help, update the test data as needed, and repeat until successful.
✅ Check Imported Data
After importing the test data, you can use yao run to query the data and check if it was imported correctly. Of course, you can also use a database management tool to check the data.
# Enter the project root directory,
# If multiple projects in your machine, ensure you are in the correct project directory.
cd /path/to/your/project
# Run the yao run command to query the data
yao run models.pets.Get '::{}'The correct output should look like this:
Run: models.pets.Get
args[0]: {}
--------------------------------------
models.pets.Get Response
--------------------------------------
[
{
"age": 3,
"breed": "Golden Retriever",
"category_id": 1,
"created_at": "2024-11-18 10:39:51",
"description": "Friendly and energetic dog.",
"id": 1,
"pet_name": "Buddy",
"updated_at": null
},
{
"age": 2,
"breed": "Siamese",
"category_id": 2,
"created_at": "2024-11-18 10:39:51",
"description": "Curious and playful cat.",
"id": 2,
"pet_name": "Whiskers",
"updated_at": null
},
{
"age": 1,
"breed": "Canary",
"category_id": 3,
"created_at": "2024-11-18 10:39:51",
"description": "Bright yellow songbird.",
"id": 3,
"pet_name": "Tweety",
"updated_at": null
}
]
--------------------------------------
✨DONE✨🎉 Congratulations
You've successfully created the data model for your pet store application. This includes demonstrating Yao's basic operations: creating database tables, importing test data, and querying data.
Next, you'll learn how to develop RESTful APIs to expose data.
- 🟢 Create and manage data in your application.
- 🔵 Develop RESTful APIs to expose data. 👉 REST API
- ⚪ Design web pages to display data. 👉 Web Page
- ⚪ Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
For more on the data model, check out the 👉 DSL References
In this section, everything can be generated by an AI chatbot. You can create an AI agent or tool for automatic generation using natural language. If you're interested in building such a tool, see the following resources:
File: documentation/en-us/02-building-your-application/04-rest-api.mdx
title: RESTFul API
related:
title: Next Steps
links:
- web-page
In previous sections, you learned how to create and manage data in your application. The pet store data models are now ready. Now, you will learn how to expose this data to the world by creating RESTful APIs.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟠 Develop RESTful APIs to expose data.
- ⚪ Design web pages to display data. 👉 Web Page
- ⚪ Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
Ensure you have read the previous documentation, and the previous steps are completed before proceeding.
Overview
RESTful API is a design standard based on the REST (Representational State Transfer) architecture. It's a lightweight, stateless, resource-oriented approach for building web services. RESTful APIs use HTTP and standard methods like GET, POST, PUT, and DELETE to manage resources.
In Yao, RESTful API functions as a Widget using API DSL to define endpoints stored in the apis directory. These endpoints operate on the built-in HTTP server.
You can adjust HTTP server settings, such as the port number, in the application configuration. More details can be found here 👉 App Configuration.
The complete REST API tutorial is available here: 👉 REST API Tutorial
For more details about API DSL, see 👉 DSL References
Step 1: Generate API DSL
In this demo, we'll create APIs to expose pet store data for client-side applications, like mobile apps.
This step demonstrates how to write prompts and generate API DSLs, which is useful for automating AI-generated applications. However, hand-writing is often quicker and more efficient in practice.
We'll create three endpoints:
GET /pets- Retrieve a list of pets, with optional category filtering.GET /pets/:id- Retrieve a pet by ID.GET /pet/categories- Retrieve a list of categories.
Send the model IDs, process descriptions, and one or more existing API DSL examples to the chatbot, and ask for assistance in generating similar API DSLs.
You can get the existing API DSL examples from the Yao documentation or other public repositories. in this case, we will use the blog api from the Yao website repository.
💬 Prompts for Generating API DSL
This is an example of a conversation with an AI chatbot to generate API DSLs. Change the prompts according to your requirements.
API DSL Samples:
[API DSL Samples]
API DSL Routes explanation:
- The api route follows the FileSystem route.
- For example /apis/v1.http.yao the root should be /apis/v1, /apis/v1/pet.http.yao the root should be /apis/v1/pet.
API DSL paths.path explanation:
- The api route should be in lowercase.
- the paths.path is the relative path to the root.
- for example /apis/v1.http.yao the root should be /apis/v1, /apis/v1/pet.http.yao the root should be /apis/v1/pet.
- In /apis/v1.http.yao, paths.path equals /pets, the endpoint is GET /v1/pets.
- In /apis/v1/pet.http.yao, paths.path equals /categories, the endpoint is GET /v1/pet/categories.
API DSL paths.in explanation:
- "$param.<name>" - The parameter name in the path.
- "$query.<name>" - The querystring parameter name.
- ":query-param" - The QueryParam, it's always named query-param.
Related Models:
pets, pet.categories
Related Processes details:
models.<model>.Find [id] [QueryParam]
models.<model>.Paginate [QueryParam] [page] [pageSize]
- I want to create a RESTful API to expose pet store data for client-side applications.
- The paths.in shoule be matched with the related models and processes arguments. for example, models.pets.Find [id] [QueryParam], the path.in should be ["$params.id", ":query-param"].
- The page and pageSize useing query string parameters, named page and pagesize.
- Each API DSL should be wrapped in a code block.
- I need three endpoints
- 1. `GET /pets` - Retrieve a list of pets, with optional category filtering.
- 2. `GET /pets/:id` - Retrieve a pet by ID.
- 3. `GET /pet/categories` - Retrieve a list of categories.
- Help me generate two API DSLs for these endpoints.
- 1. /apis/v1.http.yao for pets,
- 2. /apis/v1/pet.http.yao for pet categories.🤖 _Reply from AI Chatbot_
The AI chatbot will generate the API DSLs for you. It looks like this:
// /apis/v1.http.yao
{
"name": "Pet Store API",
"version": "1.0.0",
"description": "API to manage pet data",
"paths": [
{
"path": "/pets",
"method": "GET",
"process": "models.pets.Paginate",
"guard": "-",
"in": [":query-param", "$query.page", "$query.pagesize"],
"out": { "status": 200, "type": "application/json" }
},
{
"path": "/pets/:id",
"method": "GET",
"process": "models.pets.Find",
"guard": "-",
"in": ["$param.id", ":query-param"],
"out": { "status": 200, "type": "application/json" }
}
]
}
// /apis/v1/pet.http.yao
{
"name": "Pet Store Categories API",
"version": "1.0.0",
"description": "API to manage pet categories",
"paths": [
{
"path": "/categories",
"method": "GET",
"process": "models.pet.categories.Paginate",
"guard": "-",
"in": [":query-param", "$query.page", "$query.pagesize"],
"out": { "status": 200, "type": "application/json" }
}
]
}
//...Step 2: Save API DSLs
Before proceeding, ensure you've reviewed the previous documentation to understand the Yao application's directory structure and have created a Yao application using the Quick Start Guide.
💾 Save to APIs Directory
After generating the API DSLs, save only the JSON partials in the apis directory of your Yao application. Ensure the file and directory names are in lowercase and have a .http.yao extension.
Yao matches API DSLs using the filesystem route. The paths specified in an API DSL are relative to the root path of its DSL file, and each should begin with /api.
Ensure that the paths are in lowercase and the paths.in match the process arguments.
For example:
apis/v1.http.yao: The root router will match the path/api/v1.apis/v1/pet.http.yao: The root router will match the path/api/v1/pet.
// /apis/v1/pet.http.yao
// The root path is /api/v1
{
"name": "Pet Store Categories API",
"version": "1.0.0",
"description": "API to manage pet categories",
"paths": [
{
// is relative to the root path, /v1
// the full path is /api/v1/categories
"path": "/categories",
// Which HTTP method to use. GET, POST, PUT, DELETE, etc.
"method": "GET",
// Use the internal process to retrieve categories.
// Theres hundreds of internal processes available in Yao, you can also create your own processes.
// The internal processes can be found in Process Reference.
"process": "models.pet.categories.Paginate",
// Query parameters matching the process arguments, check the REST API tutorial for more details.
"in": [":query-param", "$query.page", "$query.pagesize"],
// The response data format. check the REST API tutorial for more details.
"out": { "status": 200, "type": "application/json" },
// Guard for checking the request's permission. check the REST API tutorial for more details.
"guard": "-"
}
]
}After saving, the apis directory should look like this:
├── apis
│ ├── v1
│ │ └── pet.http.yao
│ └── v1.http.yaoStep 3: Test API Endpoints
After saving the API DSLs, use the yao start command to start build-in http server and test the API endpoints.
📺 Start the HTTP server
Open a terminal window, enter the project directory and run the following command:
# Enter the project root directory,
# If multiple projects in your machine, ensure you are in the correct project directory.
cd /path/to/your/project
# Start the HTTP server
yao startThe correct output should look like this:
--------------------------------------------
Demo Application 0.10.4 development
--------------------------------------------
Root /Users/max/Yao/demo
Runtime standard
Data /Users/max/Yao/demo/data
Listening 0.0.0.0:5099
http://127.0.0.1:5099
--------------------------
Frontend http://127.0.0.1:5099
Dashboard http://127.0.0.1:5099/admin/login/admin
API http://127.0.0.1:5099/api
# ...
---------------------------------
API List
---------------------------------
widgets.form(10)
GET /api/__yao/form/:id/setting process: yao.form.Setting
GET /api/__yao/form/:id/find/:primary process: yao.form.Find
# ...
# The APIs added in the previous steps should be listed here.
# ---------------
v1.pet(1)
GET /api/v1/pet/categories process: models.pet.categories.Paginate
v1(2)
GET /api/v1/pets process: models.pets.Paginate
GET /api/v1/pets/:id process: models.pets.Find
# ---------------
#...If the API list is empty, verify that the YAO_ENV environment variable is set to development and that the apis directory contains the API DSLs. Additionally, if you encounter setup tips, ensure the app.yao file is present in your project's root directory. For more details, see the App Configuration section.
📺 Test the Endpoints
Ensure the HTTP server is running so that we can test the API endpoints. You can use the yao run command to execute the http.Get process. Alternatively, you can use any HTTP client like Postman, Insomnia, or cURL.
Open a new terminal window and run the following command:
# Enter the project root directory
cd /path/to/your/project
#
# Test the API endpoints
# In this example, the server is running on 127.0.0.1:5099
# you can replace it with your server IP and port.
# The IP and port are displayed in the console output when you start the HTTP server.
#
yao run http.Get http://127.0.0.1:5099/api/v1/pets
yao run http.Get http://127.0.0.1:5099/api/v1/pets '::{"page":1,"pagesize":1}'
yao run http.Get http://127.0.0.1:5099/api/v1/pets/1
yao run http.Get http://127.0.0.1:5099/api/v1/pet/categoriesThe correct output should look like this:
# yao run http.Get http://127.0.0.1:5099/api/v1/pets/1
Run: http.Get
args[0]: http://127.0.0.1:5099/api/v1/pets/1
--------------------------------------
http.Get Response
--------------------------------------
{
"code": 200,
"data": {
"age": 3,
"breed": "Golden Retriever",
"category_id": 1,
"created_at": "2024-11-18 10:39:51",
"description": "Friendly and energetic dog.",
"id": 1,
"pet_name": "Buddy",
"updated_at": null
},
"headers": {
"Content-Length": [
"175"
],
"Content-Type": [
"application/json"
],
"Date": [
"Tue, 19 Nov 2024 08:46:02 GMT"
]
},
"message": "",
"status": 200
}
--------------------------------------
✨DONE✨Step 4: Custom Process (Optional)
Beyond CRUD operations, custom processes are often needed for complex tasks.
Here, we'll use TypeScript to create a process that fetches pets by category and returns category filter options.
Scripts in Yao, saved in the scripts directory, are used to define custom processes. These scripts can be executed using the yao run command or referenced in DSLs. It runs on the server side and outputs the result in the terminal.
💾 Create Script in Scripts Directory
Create a pet.ts script file in the scripts directory. Ensure the file and directory names are in lowercase and have a .ts extension.
The Source Code and Explanation:
import { Process, log } from "@yao/runtime";
type Option = { label: string; value: number | string };
/**
* Get pet categories and return as options for select input.
*/
function FetchCategoryOptions(): Option[] {
// The Process function, provided by the Yao Runtime, executes processes and returns results.
// It's similar to the 'yao run' command.
// You can also use FS, HTTP, and other Yao Runtime APIs.
// For more details, see the Runtime References.
const categories = Process("models.pet.categories.Get", {
select: ["id", "category_name"],
limit: 100,
});
// console.log used to output information to the terminal.
// Because the script runs on the server side, the console output appears in the terminal, not in the browser.
console.log(categories);
// log.Info used to output information to the terminal.
log.Info("Categories: %s", JSON.stringify(categories));
// Return the categories as options for select input.
return categories.map(
(category) =>
({ label: category.category_name, value: category.id } as Option)
);
}After saving, the scripts directory should look like this:
├── scripts
│ └── pet.tsIf you encounter import errors in your IDE, check the tsconfig.json in project root directory. Set up the development environment and add the necessary vscode extensions to resolve them.
👉 Visual Studio Code Extensions
📺 Testing Custom Process
Execute the custom process using the yao run command.
The process ID is constructed from the file path relative to the scripts directory. To form the ID, eliminate the .ts extension and replace / with .. Each function within the script is treated as a separate process.
For instance:
- The file
scripts/pet.tsoffers a series of processes underscripts.pet.*. - The file
scripts/pet/foo.tsoffers a series of processes underscripts.pet.foo.*.
In this particular example, the process ID is scripts.pet.fetchCategoryOptions.
# Enter the project root directory
# If multiple projects in your machine, ensure you are in the correct project directory.
cd /path/to/your/project
yao run scripts.pet.FetchCategoryOptionsThe correct output should look like this:
Run: scripts.pet.FetchCategoryOptions
[
{
"category_name": "Dogs",
"id": 1
},
{
"category_name": "Cats",
"id": 2
},
{
"category_name": "Birds",
"id": 3
}
]
--------------------------------------
scripts.pet.FetchCategoryOptions Response
--------------------------------------
[
{
"label": "Dogs",
"value": 1
},
{
"label": "Cats",
"value": 2
},
{
"label": "Birds",
"value": 3
}
]
--------------------------------------
✨DONE✨💾 Add Endpoint to API DSL
To expose the custom process, add a new endpoint to the API DSL by updating the apis/v1/pet.http.yao DSL file. Upon saving the file, the HTTP server will reload automatically in development mode.
Note for Windows developers: There is a known bug with the Windows WSL environment where the server does not reload automatically if the project path is mounted in WSL. You can manually stop the server using Ctrl+C and restart it. This bug is slated to be resolved in a future update.
{
"name": "Pet Store Categories API",
"version": "1.0.0",
"description": "API to manage pet categories",
"paths": [
{
"path": "/categories",
"method": "GET",
"process": "models.pet.categories.Paginate",
"guard": "-",
"in": [":query-param", "$query.page", "$query.pagesize"],
"out": { "status": 200, "type": "application/json" }
},
// Add a new endpoint to fetch category options
{
"path": "/categories/options",
"method": "GET",
"process": "scripts.pet.FetchCategoryOptions",
"guard": "-",
"in": [],
"out": { "status": 200, "type": "application/json" }
}
]
}Test it using the yao run command:
yao run http.Get http://127.0.0.1:5099/api/v1/pet/categories/options🎉 Congratulations
You have successfully developed RESTful APIs to expose pet store data. Additionally, you have learned to create custom processes that fetch pets by category and provide category filter options. Moreover, you have explored how to collaborate with an AI to develop RESTful APIs using Yao.
If you're a front-end developer, you can accomplish what the back-end developer has achieved. If you're a back-end developer, you'll find that developing with Yao is straightforward and efficient.
Next, you will learn how to design web pages to display data.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data.
- 🔵 Design web pages to display data. 👉 Web Page
- ⚪ Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
For more details about API DSL, see:
In fact, you can automate all of the steps mentioned above using the Yao Application Generator. For more information, refer to the following resources:
File: documentation/en-us/02-building-your-application/05-web-page.mdx
title: Web Page
related:
title: Next Steps
links:
- admin-panel
In this section, we'll use the Simple User Interface (SUI) to build a dynamic web page displaying data from your application.
SUI is a built-in component-based template engine using HTML, CSS, and TypeScript to create web pages. It's AI-friendly, supports Server-Side Rendering (SSR), and requires no additional build tools.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟠 Design web pages to display data.
- ⚪ Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
Ensure you have read the previous documentation, and the previous steps are completed before proceeding.
Overview
SUI, a new feature in Yao v0.10.4, is AI-friendly and streamlines web page creation and data integration. It supports backward compatibility, enabling developers to use HTML, CSS, and TypeScript/JavaScript while promoting code reusability with a component-based architecture.
SUI requires no additional build tools and naturally supports Server-Side Rendering (SSR), enhancing SEO and making it suitable for website development.
Note: SUI is a new feature and still experimental. For advanced frontend requirements, consider using frameworks like React or Vue. Place the built files in the public directory and connect them to Yao via REST API.
Access the complete tutorials here: 👉 Website Tutorials
If you're interested in learning why we recommend SUI, read the blog post here:
👉 Why does Yao reinvent so many wheels?
Step 1: Generate Web Page
In this demo, we'll create two web pages: one to list pets and another for pet details.
The AI-generated web pages are suitable for a simple website, and you can further customize them by editing the generated content.
This step demonstrates how to write prompts to generate web pages.
💬 Prompts for Generating Web Pages
This is an example of a conversation with an AI chatbot to generate web pages. Change the prompts according to your requirements.
Model Samples:
[Model Samples]
Related Models:
pets, pet.categories
- Web Page Generation Guidelines:
- File Structure:
- **Separate Files**: Each web page should have distinct HTML, CSS, and TypeScript files named consistently (e.g., `index.html`, `index.css`, `index.ts`).
- **No Frameworks**: Avoid using frameworks or libraries. If necessary, import libraries via the script tag in the JS file.
- **Rendering Logic**: Managed by the Template Engine, so no need to implement it. Use the JS file for animations.
- **CDN Links**: For third-party libraries, include the CDN link in the JS file using `import '<CDN link>';`.
- **HTML Structure**:
- Exclude `<head>` and `<body>` tags; these are added by the SUI engine.
- Include a root element to contain the page content, e.g., `<div>PAGE CONTENT</div>`.
- CSS Guidelines:
- **Common CSS**: For consistent styling, There should be a common CSS file for all pages. the other CSS files import common CSS using `@import '@assets/[name].css';`. Use `@assets/` as required.
- **Consistency**: Use the same CSS class names and IDs as the model fields.
- **Self-contained Files**: Each page should have self-contained CSS and JS files for styles and animations.
- Template Engine Rules:
- **Data Rendering**: Use `{{ variable }}` syntax for rendering data within HTML tags.
- **Looping**: Use `s:for` for iterating over data lists, e.g., `<div s:for="items" s:for-item="pet"> <span>{{ pet.name }}</span> </div>`.
- **Conditional Rendering**: Use `s:if`, e.g., `<span s:if="pet.name">{{ pet.name }}</span>`.
- **Routing**: File system routes define web page routes. E.g., `index.html` maps to '/', 'about.html' maps to '/about'.
- **Dynamic Routes**: Represented by `[id]`, e.g., '/pet/1', '/pet/2' is '/[id]'.
- **Event Binding**: Use `s:on-click`, e.g., `<button s:on-click="handleClick" s:data-id="{{ pet.id }}">Click</button>`.
- **Event Handlers**: Implement in the TS/JS file, e.g.:
import { EventData, Component, EventDetail } from "@yao/sui";
const self = this as Component;
self.handleClick = (event: Event, data: EventData, detail: EventDetail) => {
// handle the event
// data['id'] corresponds to s:data-id="{{ pet.id }}"
};
- Design Standards:
- **Design Standard**: Develop a standard based on user requirements (color scheme, layout, font style, size, spacing, etc.).
- **CSS Variables**: Use them for color, font, and spacing in common CSS files.
- Web Page Requirements:
- **Model Fields**: Use fields in the model to generate web page content.
- **Responsive Layout**: Content should be displayed in a responsive layout, centered on the page.
- Pet store website requirements:
- **Style Guide**:
- Create a common CSS file for consistent styling, named `style.css`.
- Choose a color scheme fitting for a pet store, DO NOT use red or green, it should be friendly and inviting.
- Button should round corners, with smooth hover effects.
- Navigation items should have smooth hover effects, background color change, and text color change.
- Use Rounded corners for cards and buttons.
- Card shadow should be subtle.
- **Animations**: Use smooth animations for a polished look.
- **Category Name**: Display pet category name using `pet.category.category_name`.
- **Navigation Bar**:
- Include Company Logo, Pet List Item, link to /pet/index page, right items is signin and signup.
- Logo should be a link to the home page.
- Full-width, fixed at the top, content-centered, max-width 1200px, include a search bar.
- **Footer**:
- Use full-width, centered content, with company name and copyright information.
- Minimum height of 50px, background color as per the style guide.
Create Index and Detail pages and common CSS for the website:
- **Common CSS**:
- Create a common CSS file named `style.css` for consistent styling.
- Include color scheme, font style, size, spacing, etc.
- Use CSS variables for color, font, and spacing.
- **Index Page**:
- List pets with their categories.
- Route is '/pet/index', source directory is '/pet/index'.
- Add a 'View Details' button for each pet.
- **Detail Page**:
- Display pet details.
- Route is '/pet/[id]' source directory is '/pet/[id]'.
- `[id]` for pet details, where 'id' is the pet's ID.
- With a breadcrumb to navigate back to the pet list.🤖 _Reply from AI Chatbot_
The AI chatbot will generate web pages for you, It should be like this:
<div>
<nav>
<a href="/">Company Logo</a>
<a href="/pet/index">Pet List</a>
<input type="text" placeholder="Search..." />
<a href="/signin">Sign In</a>
<a href="/signup">Sign Up</a>
</nav>
<main>
<div s:for="pets" s:for-item="pet" class="card">
<h2>{{ pet.pet_name }}</h2>
<p>Category: {{ pet.category.category_name }}</p>
<button s:on-click="viewDetails" s:data-id="{{ pet.id }}">
View Details
</button>
</div>
</main>
<footer>
<p>Company Name © 2023</p>
</footer>
</div>@import "@assets/style.css";
/* Specific styles for the index page */
main {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
}import { EventData, Component, EventDetail } from "@yao/sui";
const self = this as Component;
self.viewDetails = (event: Event, data: EventData, detail: EventDetail) => {
const petId = data["id"];
window.location.href = `/pet/${petId}`;
};Step 2: Save Web Page
Before proceeding, ensure you've reviewed the previous documentation to understand the Yao application's directory structure and have created a Yao application using the Quick Start Guide.
📜 Directory Structure
After following the Quick Start Guide, your project root should contain three directories: data/templates/default, suis, and public.
Find out the data/templates/default directory structure below:
├── data
│ └── templates
│ └── default # Template root directory
│ ├── __assets # Assets
│ ├── __data.json # Global dynamic data
│ ├── __document.html # Document template
│ ├── index # Home page
│ │ └── index.htmlFor more information, refer to the directory structure documentation:
👉 Website Tutorials-Directory Structure
💾 Save Web Pages
SUI Page uses File System Routes for web page routing. Each page is a directory with HTML, CSS, and TypeScript files of the same name. Use [name] for dynamic routes in directory and file names.
Examples:
/indexmaps toTEMPLATE_ROOT/index/pet/[id]maps toTEMPLATE_ROOT/pet/[id]
Save generated web pages in the data/templates/default directory.
The directory structure should be:
├── data
│ └── templates
│ └── default # Template root directory
│ ├── __assets
│ │ └── style.css
│ ├── __data.json
│ ├── __document.html
│ ├── index
│ │ └── index.html
│ └── pet
│ ├── [id] # Dynamic route /pet/1, /pet/2 ...
│ │ ├── [id].css
│ │ ├── [id].html
│ │ └── [id].ts
│ └── index # Pet list page /pet
│ ├── index.css
│ ├── index.html
│ └── index.tsStep 3: Build Web Page
After saving the web pages, run the yao sui build command to build them. This generates .sui files and copies assets to the public directory.
The built-in Yao HTTP server will recognize and serve these web pages.
📺 SUI Build Command
In a new terminal, execute the following command:
# `web` is the SUI widget ID found in the `suis` directory. Each application can have multiple template engine instances.
# `default` is the template name located in the `data/templates` directory. Each engine can have multiple templates.
yao sui build web defaultThe correct output should be:
-----------------------
Public Root: /public/
Template: /templates/default
Session: {}
-----------------------
Build succeeded for production in 9ms📜 URL Rewrite
Current Yao versions lack automatic rewrite rules. Manually add them in app.yao. This will be fixed in a future release.
{
"name": "Demo Application",
"short": "Demo",
"description": "Another yao application",
"version": "0.10.4",
"adminRoot": "admin",
"public": {
// Add the http server rewrite rules here
"rewrite": [
{ "^\\/assets\\/(.*)$": "/assets/$1" }, // /assets/* -> /public/assets/*
{ "^\\/pet/index$": "/pet/index.sui" }, // /pet/index -> /public/pet/index.sui
{ "^\\/pet/(.*)$": "/pet/[id].sui" }, // /pet/xxx -> /public/pet/[id].sui
{ "^\\/(.*)$": "/$1.sui" } // Other routes, /xxx -> /xxx.sui
]
},
"optional": { "remoteCache": true }
}Restart the server after modifying the app.yao file. 👉 App Configuration
🌐 Visit in Browser
After building the web pages, you can view them in your browser. Before proceeding, ensure the Yao server is running.
Open your browser and visit the following URLs:
- http://127.0.0.1:5099/pet/index The pet list page.
- http://127.0.0.1:5099/pet/1 The pet details page.
Replace the IP address and port with your server's IP address and port.
Step 4: Integrate Data
You've successfully created web pages using SUI. This step demonstrates how to integrate data into the web pages.
📜 SUI Page Structure
Each SUI page can include up to six parts: HTML, CSS, Frontend Script, Data, Backend Script, and Configuration. Only HTML is mandatory.
| Part | Extension | Required | Description |
|---|---|---|---|
| HTML | .html | Yes | Core HTML content. |
| CSS | .css | No | Styles for the page. |
| Frontend Script | .ts | No | Scripts for browser, compiled to JS. |
| Backend Script | .backend.ts | No | Server-side scripts, like custom processes. |
| Data | .json | No | Data source, use {{ key }} in HTML for rendering. |
| Configuration | .config | No | Page settings, e.g., title, cache policy. |
💾 Data Integration
We use the backend script to fetch data from the database and use the data source file to pass the data to the HTML file.
The backend script runs on server-side, it same to scripts files. import the script in the scripts directory, or Yao Runtime APIs can be used in the backend script.
Backend Script File:
Create backend script files for pet list and pet details pages.
// pet/index/index.backend.ts
import { Process } from "@yao/runtime";
function PetList() {
const pets = Process("models.pets.Get", {
select: ["id", "pet_name", "category_id", "age", "breed", "description"],
withs: { category: { query: { select: ["id", "category_name"] } } }, // Use join query get the category name directly
});
return pets;
}// pet/[id]/[id].backend.ts
import { Process, SuiRequest, Exception } from "@yao/runtime";
function Pet(r: SuiRequest) {
// Get the pet ID from the request
const id = r.params?.id;
if (!id) {
throw new Exception("Pet ID is required", 400);
}
const pets = Process("models.pets.Find", id, {
select: ["id", "pet_name", "category_id", "age", "breed", "description"],
withs: { category: { query: { select: ["id", "category_name"] } } }, // Use join query get the category name directly
});
return pets;
}Data Source File:
// pet/index/index.json
{
// Variables prefixed with $ indicate execution of a backend script function or process.
// Values prefixed with @ indicate data retrieval from a backend script; otherwise, a process will be executed.
"$pets": "@PetList", // Excute a backend script function, Get the data
"$ping": "utils.app.ping", // Execute the process, Get the data
// Static data
"foo": { "hello": "world" }
}// pet/[id]/[id].json
{
"$pet": "@Pet" // Excute a backend script function, Get the data
}After creating the backend script and data source files, the directory structure should be:
├── data
│ └── templates
│ └── default
│ ├── __assets
│ │ └── style.css
│ ├── __data.json
│ ├── __document.html
│ ├── index
│ │ └── index.html
│ └── pet
│ ├── [id]
│ │ ├── [id].backend.ts # New backend script file for pet details page
│ │ ├── [id].css
│ │ ├── [id].html
│ │ ├── [id].json # New data source file for pet details page
│ │ └── [id].ts
│ └── index
│ ├── index.backend.ts # New backend script file for pet list page
│ ├── index.css
│ ├── index.html
│ ├── index.json # New data source file for pet list page
│ └── index.ts
├── models
│ ├── goods.mod.yao
│ ├── pet
│ │ └── categories.mod.yao
│ ├── pets.mod.yao # Modify the model DSL, add the relations
│ └── transactions.mod.yao📝 Notes:
In the backend script, use the Process function with the withs option to join the category table and directly retrieve the category name.
We should modify the Model DSL to support join queries, which ideally should have been done during the DSL file creation. It is placed here to demonstrate how to update the model DSL and maintain the application.
Open the models/pets.mod.yao file and modify the DSL add relations;
// models/pets.mod.yao
{
"name": "Pet",
"table": { "name": "pets", "comment": "Pets" },
"columns": [
//...
],
// Add the relations here
"relations": {
// category: the relation name
"category": {
"type": "hasOne", // the relation type, hasOne or hasMany
"model": "pet.categories", // the relation model widget ID
"foreign": "category_id", // the foreign key in the current model
"key": "id" // the primary key in the related model
}
},
"option": { "timestamps": true }
}For more on the data model, check out the 👉 DSL References
📺 SUI Watch Command
After saving the backend script and data source files, we need to rebuild the web pages.
Use the yao sui watch command to watch for changes and rebuild the web pages automatically.
Open a new terminal and execute the following command:
# Watch for changes and rebuild the web pages
# `web` is the SUI widget ID found in the `suis` directory. Each application can have multiple template engine instances.
# `default` is the template name located in the `data/templates` directory. Each engine can have multiple templates.
yao sui watch web defaultThe correct output should be:
-----------------------
Public Root: /public/
Template: /templates/default
Session: {}
-----------------------
Watching...
Press Ctrl+C to exitAfter executing the command, the web pages will be rebuilt automatically when changes are detected.
Building... Success (21ms)
Building... Success (18ms)The yao sui watch command generates the .sui files not compressed, and has debug information. It is recommended to use the yao build command for production.
🌐 Debug in Browser
Before starting, ensure your Yao server is running. Then, open your browser and visit:
- http://127.0.0.1:5099/pet/index?__debug for the pet list.
- http://127.0.0.1:5099/pet/1?__debug for pet details.
The __debug query string is used for debugging purposes, it ignores the page cache and data cache.
Replace 127.0.0.1:5099 with your server's IP and port.
Use the browser console to check data from the backend. Disable cache in developer tools to always get the latest data, which may show a warning in the terminal.
[SUI] The page /pet/index is not cached. file=/public/pet/index.sui DisableCache=trueStep 5: Components (Optional)
Components are reusable parts of a web page. They can be used across multiple pages, enhancing code reusability and maintainability.
In SUI, each page can be a component, can be used in other pages, use the is attribute to include a component in another page.
In this step, we'll create header and footer components to include in the pet list and pet details pages.
💾 Header and Footer Pages
Create header and footer pages in the data/templates/default directory.
<!-- data/templates/default/pet/header/header.html -->
<nav>
<a href="/">Company Logo</a>
<a href="/pet/index">Pet List</a>
<input type="text" placeholder="Search..." />
<a href="/signin">Sign In</a>
<a href="/signup">Sign Up</a>
</nav><!-- data/templates/default/pet/footer/footer.html -->
<!--
Use {% %} to access component props passed down from the parent component.
-->
<footer>
<p>Company Name © 2023 {% name %}</p>
</footer>💾 Update the Index and Detail Pages
<!-- data/templates/default/pet/index/index.html -->
<div>
<!--
Include the header component
is: the page route of the component
-->
<header is="/pet/header" active="/list"></header>
<main>
<div s:for="pets" s:for-item="pet" class="card">
<h2>{{ pet.pet_name }}</h2>
<p>Category: {{ pet.category.category_name }}</p>
<button s:on-click="viewDetails" s:data-id="{{ pet.id }}">
View Details
</button>
</div>
</main>
<footer is="/pet/footer" name="Pet List"></footer>
</div><!-- data/templates/default/pet/[id]/[id].html -->
<div>
<header is="/pet/header" active="/list"></header>
<main>
<div class="breadcrumb">
<a href="/pet/index">Back to Pet List</a>
</div>
<div class="card">
<h2>{{ pet.pet_name }}</h2>
<p>Category: {{ pet.category.category_name }}</p>
<p>Age: {{ pet.age }}</p>
<p>Breed: {{ pet.breed }}</p>
<p>Description: {{ pet.description }}</p>
</div>
</main>
<footer is="/pet/footer" name="Pet Details"></footer>
</div>For more details, check out the 👉 Website Tutorials
🎉 Congratulations
You've successfully created web pages using SUI and integrated data into them. You've also learned how to create components for code reusability.
To learn more about SUI and building web pages, check out the complete tutorials: 👉 Website Tutorials
The official Yao website was built using SUI and is an open-source project, you can find more usage examples in the repository. 👉 Yao Official Website Repo
In the next section, we'll build an admin panel to help administrators manage data in the pet store.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data.
- 🔵 Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
💬 Use the following links to generate web pages via Chat:
File: documentation/en-us/02-building-your-application/06-admin-panel.mdx
title: Admin panel
related:
title: Next Steps
links:
- cli
In this section, we will build an admin panel for the pet store application. The admin panel will help administrators manage data in the application.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data. 👉 Web Page
- 🟠 Build an admin panel to help administrators of the pet store manage data.
- ⚪ Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
Ensure you have read the previous documentation, and the previous steps are completed before proceeding.
Overview
Building an admin panel with Yao is quick and easy.
Use widgets like Table, Form, Dashboard, etc., to create a complete admin panel in minutes.
These widgets provide RESTful APIs. The frontend uses React and communicates with the backend through these APIs. The distribution files are in the Yao executable.
Before the HTTP server starts, Yao converts DSLs into RESTful APIs, serving both APIs and static files.
For a custom admin panel, use the RESTful APIs to build your own frontend and place the distribution files in the public directory. 👉 Building your component library
In this demo, we use the Table and Form widgets to create an admin panel for the pet store administrator to manage data.
The complete Admin Panel tutorial is available here: 👉 Admin Panel Tutorial
Step 1: Browse the Admin Panel
Before proceeding, ensure you've reviewed the previous documentation to understand the Yao application's directory structure and have created a Yao application using the Quick Start Guide.
To browse the admin panel, open the browser and navigate to http://127.0.0.1:5099/admin/. Replace the IP address and port with your server's IP address and port.
| Admin URL | http://127.0.0.1:5099/admin/ |
| Account | [email protected] |
| Password | demo@5099 |
Enter the account and password to log in to the admin panel.
Step 2: Generate the DSLs
We will create 4 widgets, to manage pets and pet categories in the admin panel.
- Pet Table:
tables/pets.tab.yaoDisplay pets in a table. - Pet Form:
forms/pet.form.yaoAdd or edit pets in a form. - Pet Category Table:
tables/pet-categories.tab.yaoDisplay pet categories in a table. - Pet Category Form:
forms/pet-category.form.yaoAdd or edit pet categories in a form.
Send the Model DSLs and one or more one or more existing Table/Form DSL examples to the chatbot, ask for assistance in generating similar Table/Form DSLs.
You can get an existing Table/Form DSL examples from the Yao documentation or other public repositories. in this case, we get them from the Yao website repository.
| Source URL |
|---|
| 👉 article.tab.yao |
| 👉 category.tab.yao |
| 👉 article.form.yao |
| 👉 category.form.yao |
💬 Prompts for Generating Table and Form DSLs
This is an example of a conversation with an AI chatbot to generate table and form DSLs. Change the prompts according to your requirements.
# DSL Generation Task
## DSL Samples Reference
- **Table DSL Samples**: [Table DSL Samples]
- **Form DSL Samples**: [Form DSL Samples]
- **Model DSLs**: [Model DSLs]
## Requirements
### 1. Generate a Table DSL for Model `pets`
- **File**: `pets.tab.yao`
- **Path**: `pets`
- **Fields**: Use the fields from the Model `Pet`, which are suitable for a table.
- **Add and Edit**: The Form Window opens from the right side.
- **Bind**: Bind the table to `model.pets` and the form `pets`.
### 2. Generate a Form DSL for Model `pets`
- **File**: `pets.form.yao`
- **Path**: `pets`
- **Fields**: Use the fields from the Model `Pet`, and ensure the layout is easy to use.
- **Bind**: Bind the form to the table `pets`.
### 3. Generate a Table DSL for Model `pet.categories`
- **File**: `pet/category.tab.yao`
- **Path**: `pet/categories`
- **Name**: `pet.categories`
- **Fields**: Use the fields from the Model `PetCategory`, which are suitable for a table.
- **Add and Edit**: The Form Window opens from the right side.
- **Bind**: Bind the table to `model.pet.categories` and the form `pet.categories`.
### 4. Generate a Form DSL for Model `pet.categories`
- **File**: `pet/categories.form.yao`
- **Path**: `pet/categories`
- **Name**: `pet.categories`
- **Fields**: Use the fields from the Model `PetCategory`, and ensure the layout is easy to use.
- **Bind**: Bind the form to the table `pet.categories`.
## Output Instructions
For each DSL:
1. Return the code inside a **separate code block**.
2. Add comments indicating the respective **file name** above each block, use // for comments.
### Example Output Format
```json
// pets.tab.yao
<Generated Table DSL for Model pets>
```
```json
// pets.form.yao
<Generated Form DSL for Model pets>
```
```json
// pet/categories.tab.yao
<Generated Table DSL for Model pet.categories>
```
```json
// pet/categories.form.yao
<Generated Form DSL for Model pet.categories>
```🤖 _Reply from AI Chatbot_
The AI chatbot will generate the table and form DSLs for you. It looks like this:
// pet/category.tab.yao
{
"name": "Pet Categories",
"action": {
"bind": {
"model": "pet.categories",
"option": { "form": "pet.categories" }
},
"before:search": "scripts.hooks.OrderBySort"
},
"layout": {
"header": {},
"primary": "id",
"filter": {
"columns": [{ "name": "Category Name" }],
"actions": [
{
"title": "Add Category",
"icon": "icon-plus",
"style": "primary",
"action": [
{
"name": "openModal",
"type": "Common.openModal",
"payload": {
"byDrawer": { "mask": true },
"Form": { "type": "add", "model": "pet.categories" }
}
}
]
}
]
},
"table": {
"columns": [
{ "name": "ID", "width": 60 },
{ "name": "Category Name", "width": 200 },
{ "name": "Description", "width": 300 }
],
"operation": {
"fold": false,
"actions": [
{
"style": "primary",
"title": "Edit",
"icon": "icon-edit-2",
"action": [
{
"name": "openModal",
"type": "Common.openModal",
"payload": {
"byDrawer": { "mask": true },
"Form": {
"type": "edit",
"model": "pet.categories",
"params": { "id": "{{id}}" }
}
}
}
]
},
{
"style": "danger",
"title": "Delete",
"icon": "icon-trash-2",
"action": [
{
"name": "Confirm",
"type": "Common.confirm",
"payload": {
"title": "Please confirm to delete [{{ category_name }}]",
"content": "This action is irreversible! The category will be permanently deleted."
}
},
{ "name": "Delete", "type": "Table.delete", "payload": {} }
]
}
]
}
}
},
"fields": {
"filter": {
"Category Name": {
"bind": "where.category_name.match",
"edit": {
"type": "Input",
"props": { "placeholder": "Category Name" }
}
}
},
"table": {
"ID": {
"bind": "id",
"view": { "type": "Text" }
},
"Category Name": {
"bind": "category_name",
"view": { "type": "Text", "props": { "weight": "medium" } },
"edit": { "type": "Input", "props": { "placeholder": "Category Name" } }
},
"Description": {
"bind": "description",
"view": { "type": "Text" },
"edit": {
"type": "TextArea",
"props": { "placeholder": "Description" }
}
}
}
}
}// pet/categories.form.yao
{
"name": "Pet Category",
"action": { "bind": { "table": "pet.categories" } },
"layout": {
"primary": "id",
"actions": [
{
"title": "Save",
"icon": "icon-save",
"style": "primary",
"showWhenAdd": true,
"action": [{ "name": "Submit", "type": "Form.submit" }]
},
{
"title": "Delete",
"icon": "icon-trash-2",
"style": "danger",
"action": [
{
"name": "Confirm",
"type": "Common.confirm",
"payload": {
"title": "Please confirm to delete [{{ category_name }}]",
"content": "This action is irreversible!"
}
},
{ "name": "Delete", "type": "Table.delete", "payload": {} }
]
},
{
"title": "Close",
"icon": "icon-arrow-left",
"showWhenAdd": true,
"showWhenView": true,
"action": [
{ "name": "CloseModal", "type": "Common.closeModal", "payload": {} }
]
}
],
"form": {
"sections": [
{
"columns": [
{ "name": "Category Name", "width": 24 },
{ "name": "Description", "width": 24 }
]
}
]
}
},
"fields": {
"form": {
"Category Name": {
"bind": "category_name",
"edit": {
"type": "Input",
"props": { "placeholder": "Input the category name" }
}
},
"Description": {
"bind": "description",
"edit": {
"type": "TextArea",
"props": { "placeholder": "Input the description of the category" }
}
}
}
}
}Step 3: Save the DSLs
After generating the DSLs, save them in the tables and forms directories in your Yao application.
💾 Save to Tables and Forms directories
| Widget Type | Widget ID | Path |
|---|---|---|
| Table | pets | tables/pets.tab.yao |
| Table | pet.categories | tables/pet-categories.tab.yao |
| Form | pets | forms/pets.form.yao |
| Form | pet.categories | forms/pet-categories.form.yao |
After saving the DSLs, the tables and forms directories should look like this:
├── forms
│ ├── account.form.yao
│ ├── pet
│ │ └── categories.form.yao
│ └── pets.form.yao
├── tables
│ ├── account.tab.yao
│ ├── pet
│ │ └── categories.tab.yao
│ └── pets.tab.yaoStep 4: Test the Admin Panel
In development mode, the HTTP server auto-reloads widgets when DSLs are updated. Just refresh the browser to see the changes in the admin panel.
📜 Admin Panel Routes
The Widgets for the Admin Panel are available at the following routes:
https://127.0.0.1:5099/admin/x/{widget-type}/{widget-id}
| Widget Type | Description |
|---|---|
| Table | Table view of the data. |
| Form | Form view of the data. |
| Dashboard | Dashboard view. |
| Chart | Chart view. |
Table Routes
https://127.0.0.1:5099/admin/x/Table/{widget-id}
| Widget ID | Path | Route |
|---|---|---|
| pets | tables/pets.tab.yao | http://127.0.0.1:5099/admin/x/Table/pets |
| pet.categories | tables/pet/categories.tab.yao | http://127.0.0.1:5099/admin/x/Table/pet.categories |
Form Routes
- https://127.0.0.1:5099/admin/x/Form/{widget-id}/{data-id}/view view mode
- https://127.0.0.1:5099/admin/x/Form/{widget-id}/{data-id}/edit edit mode
data-id is 0 for add mode.
| Widget ID | Path | Route |
|---|---|---|
| pets | forms/pets.form.yao | http://127.0.0.1:5099/admin/x/Form/pets/0/edit |
| pet.categories | forms/pet/categories.form.yao | http://127.0.0.1:5099/admin/x/Form/pet.categories/0/edit |
🌐 Debug in Browser
- Log in to the admin panel and navigate to routes in the URL to view the tables.
Note: Stay in the same tab to avoid being logged out. - Open the browser’s developer tools to check for errors in the console.
- Errors may occur if components are misconfigured or DSLs are incorrectly generated. Debug using the error messages, fix the DSLs, and refresh the page to apply changes.
💾 Add to Menu
After testing the widgets, add them to the admin panel menu.
The menu logic is defined in the app.yao file, with flows.menu as the default process. 👉 App Configuration
There are two types of menu item icons: Material and Feather.
| Icon Type | Usage | Example | URL |
|---|---|---|---|
| Feather | icon-[name] | icon-activity | Feather Icons |
| Material | material-[name] | material-favorite | Material Icons |
- open the
flows/menu.flow.yaofile. - Add the menu items to the
items.itemsarray. - Relogin to the admin panel to view the new menu items.
{
"name": "Menu",
"nodes": [],
"output": {
"items": [
{
"name": "Generator",
"path": "/iframe?src=https://moapi.ai/iframe/yaoapp", // For production
"icon": "material-mark_chat_unread"
},
// Add the new menu items here
{
"name": "Pets", // Menu Item Name
"path": "/x/Table/pets", // The default route should navigate to a sub-menu.
"icon": { "name": "material-pets", "size": 22 }, // Material Icon
"children": [
// Submenu
{
"name": "Pets",
"path": "/x/Table/pets",
"icon": { "name": "material-pet_supplies", "size": 22 }
},
{
"name": "Pet Categories",
"path": "/x/Table/pet.categories",
"icon": { "name": "material-category", "size": 22 }
}
]
}
],
"setting": [
{
"icon": { "name": "material-person_pin_circle", "size": 22 },
"name": "Accounts",
"path": "/x/Table/account"
}
]
}
}Step 5: Hooks (Optional)
Hooks control data handling in the admin panel and enable custom data processing.
Widgets such as Table, Form, and Dashboard support hooks, which can be added directly to their DSLs.
📝 Add Hooks to DSLs
// tables/pets.tab.yao
{
"name": "Pets",
"action": {
"bind": { "model": "pets", "option": { "form": "pets" } },
"before:search": "scripts.pet.BeforeSearch", // Before Search Hook
"after:search": "scripts.pet.AfterSearch", // After Search Hook
"save": { "process": "scripts.pet.Save" } // Use custom process for saving pet data.
}
// .....
}// scripts/pet.ts
import { Process, QueryParam, SearchResult, log } from "@yao/runtime";
/**
* BeforeSearch hook for the pet search process.
* @param query Query parameters for the pet search process.
* @param page Current page number.
* @param pagesize Number of items per page.
* @returns [QueryParam,number,number] fixed query, page, and pagesize.
*/
function BeforeSearch(query: QueryParam, page, pagesize: number) {
// Join the category table to get the category name.
query.withs = { category: { query: { select: ["id", "category_name"] } } };
console.log(query, page, pagesize);
return [query, page, pagesize];
}
/**
* AfterSearch hook for the pet search process.
* @param response Search result of the pet search process.
* @returns SearchResult<Record<string, any>> Modified search result.
*/
function AfterSearch(response: SearchResult<Record<string, any>>) {
// Flatten the category object and add the category name to the pet object.
response.data?.forEach((pet: Record<string, any>) => {
pet.category_name = pet.category.category_name;
});
console.log(response);
return response;
}
/**
* Save pet data. custom process for saving pet data.
* @param data
* @returns
*/
function Save(payload: Record<string, any>) {
console.log(payload);
return Process("models.pets.Save", payload);
}🎉 Congratulations
You’ve built a pet store admin panel with widgets like Table, Form, and Dashboard in minutes.
Explore advanced features, customizations, and more widgets with our tutorials and documentation:
In the next section, we will create backend commands for task scheduling.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data. 👉 Web Page
- 🟢 Build an admin panel to help administrators of the pet store manage data.
- 🔵 Create backend commands for task scheduling. 👉 CLI
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
From data models to RESTful APIs, web design, and admin panels, we’ve built a full app entirely with AI-generated code. Simple apps can be created by AI alone, with developers stepping in for complex features.
💬 Build App via Chat:
File: documentation/en-us/02-building-your-application/07-cli.mdx
title: Command Line Interface
related:
title: Next Steps
links:
- ai-integration
In this section, We’ll create a custom process to generate a daily report of all pets in the store, scheduled to run at 23:59 every day.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data. 👉 Web Page
- 🟢 Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- 🟠 Create backend commands for task scheduling.
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
Ensure you have read the previous documentation, and the previous steps are completed before proceeding.
Overview
The CLI lets you interact with your application through commands. It can be used to create custom tasks like generating reports, sending emails, and more.
To schedule commands, there are two options:
Schedule Widget - Define the schedule, specify the process, and set the execution time directly within the widget.
Cron Jobs - Use system cron jobs to run
yao runat specified times.
Create a Process
Develop a process that generates a daily report of all pets in the store. This process will:
- Query the database for pets created on the specified date.
- Group them by category.
- Save the report as a CSV file.
This example demonstrates the comprehensive programming capabilities of Yao.
// scripts/schedules/report.ts
import { FS, Query, log } from "@yao/runtime";
/**
* Generate a report for the given date.
* Tests:
* yao run scripts.schedules.report.Generate "2024-11-25"
* yao run scripts.schedules.report.Generate "2024-11-18"
* @param date The date to generate the report for. If not provided, today's date is used.
*/
function Generate(date?: string) {
// Parse the date and get the start and end of the day
const time = date ? new Date(date) : new Date();
const day = `${time.getFullYear()}-${time.getMonth() + 1}-${time.getDate()}`;
const from = `${day} 00:00:00`;
const to = `${day} 23:59:59`;
// Log the date range
console.log(`Generating report for ${day}...`);
log.Trace("Generating report for %s...", day);
// Query data from database
// For details, please refer to Query DSL reference
const qb = new Query("default");
const rows = qb.Get({
from: "pets",
debug: true,
select: [
"category_id",
"category.category_name",
":COUNT(pets.id) as total",
],
joins: [
{
left: true,
from: "pet_categories as category",
key: "category_id",
foreign: "category.id",
},
],
wheres: [
{ field: "pets.created_at", ">=": from },
{ field: "pets.created_at", "<=": to },
],
groups: ["category_id"],
});
// Save the report to a file
// For details, please refer to Yao Runtime API reference
const fs = new FS("data");
const file = `/reports/${day}.csv`; // eg /data/reports/2024-11-25.csv
const content = rows
.map(
(row: Record<string, any>) =>
`${row.category_id},${row.category_name},${row.total}`
)
.join("\n");
fs.WriteFile(file, content);
console.log(`Report generated at ${file}`);
log.Trace("Report generated at %s", file);
}Schedule via Schedule Widget
Create a new schedule widget to run the process at 23:59 every day.
// schedules/report.sch.yao
{
"name": "Generate Report at 23:59", // The name of the schedule
// The cron expression to run the process.
"schedule": " */1 * * * *", // */1 * * * * for every minute, test only
// "schedule": "0 59 23 * * *", // 23:59 every day
"process": "scripts.schedules.report.Generate", // The process to run
"args": [] // The arguments to pass to the process
}The directory structure should look like this:
├── schedules
│ └── report.sch.yao # Schedule Widget
├── scripts
│ ├── ai
│ │ └── neo.ts
│ ├── pet.ts
│ ├── schedules
│ │ └── report.ts # Custom Process for generating reports
│ ├── tests.ts
│ └── utils.tsWhen the HTTP server is running, scheduled tasks will execute at their specified times, and the list of schedules will be displayed in the terminal.
---------------------------------
Schedules List (1)
---------------------------------
[Schedule] */1 * * * * report Generate Report at 23:59 Process: scripts.schedules.report.GenerateSchedule via Cron Jobs
You can also use system cron jobs to run the process at 23:59 every day.
# Open the crontab file
crontab -e
# Add the following line to the crontab file
59 23 * * * cd /path/to/your/project && yao run scripts.schedules.report.Generate
# Save and exit the crontab fileSilent Mode
if you want use yao run in shell script, you can use silent mode to avoid the output of the command.
yao run scripts.schedules.report.Generate --silent
# or
yao run -s scripts.schedules.report.GenerateExample:
# Run the command in silent mode
result=$(yao run scripts.schedules.report.Generate --silent)
echo $result🎉 Congratulations
You have successfully created a custom process to generate a daily report of all pets in the store, scheduled to run at 23:59 every day.
Next, you can integrate AI for chatbots, image generation, and enhanced user input.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data. 👉 Web Page
- 🟢 Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- 🟢 Create backend commands for task scheduling.
- ⚪ Integrate AI for chatbots, image generation, and enhanced user input. 👉 AI Integration
💬 Build App via Chat:
File: documentation/en-us/02-building-your-application/08-ai-integration.mdx
title: AI Integration
related:
title: Next Steps
links:
- deploying-your-application
In this section, we’ll integrate AI into our application to enhance user input, generate images, and create chatbots.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data. 👉 Web Page
- 🟢 Build an admin panel to help administrators of the pet store manage data.
- 🟢 Create backend commands for task scheduling. 👉 CLI
- 🟠 Integrate AI for chatbots, image generation, and enhanced user input.
Ensure you have read the previous documentation, and the previous steps are completed before proceeding.
Overview
Integrating AI into your Yao application enhances user experience, automates tasks, and unlocks valuable insights.
Key Use Cases:
- Chatbots: A built-in assistant that serves as the user's natural language interface to interact with your application.
- AI-Generated Content: Use prompts as a Process to generate text, images, and other content dynamically with AI.
- AI-Powered Input: Enhance user input with features like auto-complete, spell-check, translation, and image generation.
- AI Agents: Create intelligent agents that automate tasks by accessing application data, Yao Processes, and runtime APIs.
Connector
Yao supports integration with the OpenAI API. If you're using a different AI API, you can convert its requests and responses to match the OpenAI format.
📜 Create Connectors
Use the Connector Widget to configure the API key and other settings
// connectors/gpt-4o.conn.yao
{
"label": "Model gpt-4o", // The name of the model for display
"type": "openai", // The type of the connector, openai only for now
"options": {
"model": "gpt-4o", // The AI Model name
"key": "$ENV.OPENAI_API_KEY", // The API key, supports environment variables
"proxy": "http://ip:port" // Optional proxy server, if needed
}
}// connectors/text-embedding-ada-002.conn.yao
{
"label": "text-embedding-ada-002",
"type": "openai",
"options": {
"model": "text-embedding-ada-002",
"key": "$ENV.OPENAI_API_KEY"
}
}The directory structure for the connectors is as follows:
├── connectors
│ ├── gpt-4o.conn.yao
│ └── text-embedding-ada-002.conn.yao📺 Start the Http Server
Use yao start to start the server.
If used the environment variable, you can set it in the .env file in your project root directory. 👉 App Configuration
# ...
OPENAI_API_KEY=your-api-key
# ....After the application started, the connectors are loaded and available for use in your application.
---------------------------------
Connectors List (2)
---------------------------------
[Connector] gpt-4o loaded
[Connector] text-embedding-ada-002 loadedChatbots
The built-in chatbot, Neo, is configured using the file neo/neo.yml. Once configured, you can access the chatbot from the bottom-right corner of the admin panel.
Open the neo/neo.yml file and configure the chatbot settings, set the connector to gpt-4o .
# guard: "scripts.neo.Guard" # Custom guard, you can use it to check if the user is allowed to access the AI model
conversation:
connector: default
table: yao_neo_conversation
max_size: 10
ttl: 3600
connector: "gpt-4o" # Enter the connector widget ID
prepare: "scripts.ai.neo.Prepare" # Prepare hook, you can use it to modify the input before sending it to the AI model.
write: "scripts.ai.neo.Write" # Write hook, you can use it to modify the output before sending it to the user
option:
temperature: 0.6
# CORS Settings, witch domains are allowed to access the chatbot API
allows:
- "http://127.0.0.1:8000"
- "http://127.0.0.1:5099"
- "http://localhost:5099"
- "http://localhost:8000"Open browser and navigate to the admin panel, you can see the chatbot in the bottom-right corner.
AI-Generated Content
Use the AIGC widget make a Process to generate text, images, and other content dynamically with AI.
Note: The AIGC widget DSL is in YAML format, used for inputting prompts.
📜 Create a AIGC widget
The AIGC widget uses the .ai.yml file extension.
Create a AIGC widget file aigc/translate.ai.yml and set connector to gpt-4o, and add prompts.
# Translate
name: Translate
connector: gpt-4o # Specify the connector widget ID
prompts:
- role: system
content: |
- Translate the message to French.📺 Execute the Process
The AIGC widget provides the "aigcs.[widget-id]" process to execute the prompts.
Open terminal and run the command yao run aigcs.translate.
cd /path/to/your/project
yao run aigcs.translate HelloThe output will be displayed in the terminal.
Run: aigcs.translate
args[0]: Hello
--------------------------------------
aigcs.translate Response
--------------------------------------
Bonjour
--------------------------------------
✨DONE✨AI-Powered Input
Each component in the Form DSL has an ai property. When set, an AI icon will appear in the top-right corner of the input box. Clicking the icon lets you enter a prompt and send it to the Neo chatbot by pressing the "Send" button. This sends a special message, including the context, prompt, and current form data.
In neo/neo.yml, you can use the Prepare hook to modify the input before sending it to the AI model, and the Write hook to modify the output before it's sent to the user.
By default, Prepare and Write hooks are defined in scripts/ai/neo.ts during installation.
// scripts/ai/neo.ts
import { io, neo } from "@yao/runtime";
/**
* Neo Prepare hook
*/
function Prepare(ctx: neo.Context, messages: neo.Message[]): neo.Message[] {
return messages;
}
/**
* Neo Write hook
*/
function Write(
ctx: neo.Context,
messages: neo.Message[],
response: neo.Response,
content?: string,
writer?: io.ResponseWriter
): neo.Response[] {
return [response];
}Modify the Form DSL
Modify the Form DSL to include the ai property for fields.form.Description.
{
// ....
"fields": {
"form" {
// ....
"Description": {
"bind": "description",
"edit": {
"type": "TextArea",
"props": {
// Add the ai property here
"ai": {
"placeholder": "Input the prompt, and I will generate the description for you."
},
"placeholder": "Input the description of the pet"
}
}
}
// ....
}
}
// ....
}💾 Modify the Prepare and Write Hooks
You can modify the Prepare and Write hooks to customize the input and output of the chatbot.
neo/neo.ts
Prepare: Before sending the input to the AI model, add special prompts for the field input
/**
* Neo Prepare hook
*/
function Prepare(ctx: neo.Context, messages: neo.Message[]): neo.Message[] {
// Print the namespace and field to the terminal for debugging
console.log(`Prepare: ${ctx.namespace}`);
console.log(ctx.namespace);
console.log(ctx.field);
console.log(ctx.formdata);
// the namespace is "Table-Page-pets/Form-Modal-pets" and the field is "description", Field is the current field that the user is interacting with.
if (ctx.namespace === "Table-Page-pets/Form-Modal-pets") {
switch (ctx.field?.bind) {
case "description":
// Add a prompt to generate a description for the pet
const lastMessage = messages[messages.length - 1];
const prompts: neo.Message[] = [
{
role: "system",
content: `FORMDATA: ${JSON.stringify(ctx.formdata || {})}`,
},
{
role: "system",
content: `
- According to the formdata I provided, generate a description for the pet.
- The description should be a short paragraph that describes the pet.
- Answer me the description only, do not include any other information.
`,
},
lastMessage,
];
// For debugging, print the prompts to the terminal
console.log("--- Prompts Content---");
console.log(prompts);
return prompts;
}
}
// The default behavior is to return the messages as-is
return messages;
}Write: After receiving the output from the AI model, modify the output add action to update the form data.
/**
* Neo Write hook
*/
function Write(
ctx: neo.Context,
messages: neo.Message[],
response: neo.Response,
content?: string,
writer?: io.ResponseWriter
): neo.Response[] {
// Print the namespace and field to the terminal for debugging
console.log(ctx.namespace);
console.log(ctx.field);
console.log(ctx.formdata);
// the namespace is "Table-Page-pets/Form-Modal-pets" and the field is "description", Field is the current field that the user is interacting with.
if (
ctx.namespace === "Table-Page-pets/Form-Modal-pets" &&
ctx.field?.bind === "description"
) {
const { namespace, field } = ctx;
if (content === undefined) {
return [response];
}
if (!response.done) {
return [response];
}
response.actions = [
{
name: "Done",
type: "Common.emitEvent",
payload: { key: `${namespace}/${field.bind}/unloading` },
}, // mark the field as done
{
name: "SetFieldsValue",
type: "Common.emitEvent",
payload: {
key: `${namespace}/setFieldsValue`,
value: { description: content },
},
}, // Update the formdata with the description field
{
name: "SetNeoVisible",
type: "Common.emitEvent",
payload: {
key: `app/setNeoVisible`,
value: { visible: true },
},
}, // show the chatbot, for editing the output
];
console.log("--- Response Actions ---");
console.log(response.actions);
console.log("--- Response ---");
}
// the default behavior is to return the response as-is
return [response];
}For more information, refer to the 👉 AI-powered Input Tutorial
AI Agents
Through the Prepare and Write hooks, you can create intelligent agents that automate tasks by accessing application data, Yao Processes, and runtime APIs.
Note: The AI Agent feature is still experimental and may change in future versions. For security reasons, some limitations might be added later.
Organizing Your AI Agents
- Directory Structure: Place all your AI agents in the
agentsdirectory. - Interface Definition: Define the
Agentinterface. - Implementation: Implement the logic for each agent.
By following these steps, you can streamline task automation within your application.
├── scripts
│ ├── ai
│ │ ├── actions.ts
│ │ ├── agents
│ │ │ ├── article
│ │ │ │ ├── content.ts
│ │ │ │ ├── cover.ts
│ │ │ │ └── share_message.ts
│ │ │ ├── defaults.ts
│ │ │ ├── playground.ts
│ │ │ └── select.ts
│ │ ├── aigcs
│ │ │ └── doc.ts
│ │ ├── neo.ts
│ │ └── utils.tsexport interface IAgent {
Prepare: (context: Context, messages: Message[]) => Message[];
Write: (
context: Context,
messages: Message[],
response: Response,
content?: string,
writer?: io.ResponseWriter
) => Response[];
}To maintain clarity and simplicity, keep the Prepare and Write hooks in scripts/ai/neo.ts straightforward. Delegate the complex logic to the agents.
import { io, neo } from "@yao/runtime";
import { DefaultChat, DefaultInput } from "./agents/defaults";
import { SelectAgent } from "./agents/select";
/**
* Neo Prepare hook
*/
function Prepare(ctx: neo.Context, messages: neo.Message[]): neo.Message[] {
const { namespace, field } = ctx;
const agent = SelectAgent(ctx);
if (agent) {
return agent.Prepare(ctx, messages);
}
// AI Powered Input
if (namespace && field && field.bind) {
return DefaultInput.Prepare(ctx, messages);
}
// AI Chatbot
return DefaultChat.Prepare(ctx, messages);
}
/**
* Neo Write hook
*/
function Write(
ctx: neo.Context,
messages: neo.Message[],
response: neo.Response,
content?: string,
writer?: io.Writer
): neo.Response[] {
const { namespace, field } = ctx;
const agent = SelectAgent(ctx);
if (agent) {
return agent.Write(ctx, messages, response, content, writer);
}
// AI Powered Input
if (namespace && field && field.bind) {
return DefaultInput.Write(ctx, messages, response, content, writer);
}
// AI Chatbot
return DefaultChat.Write(ctx, messages, response, content);
}For more information on creating and managing AI agents, please refer to the following resources:
- 👉 AI Agent Tutorial: A comprehensive guide to help you get started with AI agents.
- 👉 Yao Website Repo: Explore the Yao Website Repository for more examples of AI agents and best practices.
These resources provide valuable insights and examples to help you enhance your AI agent development.
🎉 Congratulations
You have successfully integrated AI into your application to enhance user input and create chatbots.
- 🟢 Create and manage data in your application. 👉 Data Model
- 🟢 Develop RESTful APIs to expose data. 👉 REST API
- 🟢 Design web pages to display data. 👉 Web Page
- 🟢 Build an admin panel to help administrators of the pet store manage data. 👉 Admin Panel
- 🟢 Create backend commands for task scheduling. 👉 CLI
- 🟢 Integrate AI for chatbots, image generation, and enhanced user input.
Next, you can deploy your application to make it accessible to users.
💬 Build App via Chat:
File: documentation/en-us/02-building-your-application/09-app-configuration.mdx
title: App configuration
Your application root directory contains three key configuration files:
| File | Description |
|---|---|
app.yao |
This file contains the configuration for your application. |
tsconfig.json |
This file contains the TypeScript configuration for your application. |
.env |
This file contains the environment variables for your application. |
app.yao
The app.yao file is the main configuration file for your application. It defines essential details like the application name, version, description, and other settings.
Here’s an example structure of the app.yao file:
{
"name": "Demo Application", // Application name
"short": "Demo", // Short name for the application
"description": "Another yao application", // Brief description
"version": "0.10.4", // Application version
"adminRoot": "admin", // Admin panel root path (default: "admin")
/**
* Hook: setup
* Script to run after installation. Useful for initializing application data.
*/
"setup": "scripts.tests.AppSetup",
/**
* Hook: afterLoad
* Introduced in yao v0.10.4
* Runs after the application is loaded. Use this to dynamically load DSLs before the HTTP server starts.
*/
"afterLoad": "scripts.tests.AppAfterLoad",
/**
* Hook: afterMigrate
* Introduced in yao v0.10.4
* Runs after the application is migrated. Ideal for setting up initial data during `yao migrate`.
*/
"afterMigrate": "scripts.tests.AppAfterMigrate",
/**
* Custom menu process for the admin panel.
* Default process: "flows.menu". Create your own if needed.
* @see /flows/menu.flow.yao
*/
"menu": { "process": "flows.menu", "args": [] },
/**
* Introduced in yao v0.10.4
* HTTP Server Root Directory Configuration (Optional)
*/
"public": {
/**
* Maps public backend script source roots to real paths.
* Useful for SUI backend script development in dev mode.
*/
"sourceRoots": { "/public": "/data/templates/default" },
// Routes for SUI web pages
"rewrite": [
{ "^\\/assets\\/(.*)$": "/assets/$1" }, // SUI assets
{ "^\\/(.*)$": "/$1.sui" } // File system routes
]
},
"optional": {
/**
* Enables remote cache to reduce requests (e.g., Select Component options queries)
* by caching data in the browser.
*/
"remoteCache": false,
/**
* Introduced in yao v0.10.4
* Admin menu configuration:
* - layout: "1-column" (single column), "2-columns" (menu + sub-menu)
* - hide: hides the menu and sub-menu
* - showName: displays menu names
*/
"menu": { "layout": "2-columns", "showName": true },
/**
* Optional AI chatbot service configuration.
* If omitted, the Neo service will not be available.
*/
"neo": { "api": "/neo" }
},
/**
* Introduced in yao v0.10.4
* Moapi service configuration (Optional).
* Moapi is not required for the application to function.
* Get a secret key from Moapi or use an AI Connector.
* @see https://moapi.ai for details.
*/
"moapi": {
"channel": "global",
"mirrors": ["https://api.moapi.ai"],
"secret": "$ENV.MOAPI_SECRET" // Supports environment variables
}
}tsconfig.json
The tsconfig.json file is the TypeScript configuration file for your application. It defines the TypeScript compiler options and paths for your application.
Here’s an example structure of the tsconfig.json file:
{
"compilerOptions": {
"target": "es6", // Do not change
"paths": {
"@yao/*": ["./.types/*"], // Yao Runtime APIs and types. ( Do not change )
"@scripts/*": ["./scripts/*"] // Custom Process Scripts. ( Do not change )
},
"lib": ["es2017", "dom"] // dom is required for SUI web pages
}
}Environment variables
The .env file contains the environment variables for your application. It is used to store sensitive information like API keys, database credentials, and other secrets.
You can add custom environment variables to the .env file and access them in your application through the utils.env.* processes.
Here’s an example structure of the .env file:
YAO_DB_DRIVER="sqlite3" # Database driver (sqlite3, mysql, postgres)
YAO_DB_PRIMARY="./db/yao.db" # Primary database file or DSN
YAO_ENV="development" # Application environment (development, production)
YAO_HOST="0.0.0.0" # Application http server listen address (default: 0.0.0.0, all interfaces)
YAO_PORT=5099 # Application http server listen port (default: 5099)
YAO_LOG_MODE="TEXT" # Log mode (TEXT, JSON)
YAO_LOG="./logs/application.log" # Log file path
YAO_SESSION_STORE="file" # Session store (file, redis)
YAO_SESSION_FILE="./db/.session" # Session file path | Required for file session store📜 Database Connection Strings
For SQLite:
SQLite connection is the file path to the database file:
"/path/to/database.db"Example:
YAO_DB_DRIVER="sqlite3"
YAO_DB_PRIMARY="./db/yao.db"For MySQL:
MySQL support is available starting from version 5.7, with version 8.0 or higher recommended.
MySQL connection strings are in the format:
"[user]:[password]@tcp([server]:[port])/[database]?charset=utf8mb4&parseTime=True&loc=Local"Example:
YAO_DB_DRIVER="mysql"
YAO_DB_PRIMARY="webuser:webpass@tcp(127.0.0.1:3306)/website?charset=utf8mb4&parseTime=True&loc=Local"For PostgreSQL:
Support for PostgreSQL is planned for future releases. Stay tuned for updates! 😊
📜 Full List of Environment Variables
| Variable | Description | Default Value |
|---|---|---|
YAO_ENV |
Application mode: production or development. |
production |
YAO_LANG |
Default language setting (e.g., en-us, zh-cn). |
en-us |
YAO_TIMEZONE |
Default time zone for the application. | - |
YAO_DATA_ROOT |
Path for data storage. | ./data |
YAO_EXTENSION_ROOT |
Root path for plugins. | ./plugins |
YAO_HOST |
Server host address. | 0.0.0.0 |
YAO_PORT |
Server port for HTTP requests. | 5099 |
YAO_LOG |
Log file path. | ./logs/application.log |
YAO_LOG_MODE |
Log format: TEXT or JSON. |
TEXT |
YAO_LOG_MAX_SIZE |
Maximum log file size in MB. | 100 |
YAO_LOG_MAX_AGE |
Maximum age of log files in days. | 7 |
YAO_LOG_MAX_BACKUPS |
Number of log backups to retain. | 3 |
YAO_LOG_LOCAL_TIME |
Use local time for log timestamps. | true |
YAO_JWT_SECRET |
Secret key for JWT authentication. | - |
YAO_DB_DRIVER |
Database driver (sqlite3, mysql, postgres). |
sqlite3 |
YAO_DB_PRIMARY |
Primary database connection string. | ./db/yao.db |
YAO_DB_SECONDARY |
Secondary database connection string (optional). | - |
YAO_DB_AESKEY |
Encryption key for secure data storage. | - |
YAO_ALLOW_FROM |
List of allowed domains for CORS | - |
YAO_SESSION_STORE |
Session storage type: file or redis. |
file |
YAO_SESSION_FILE |
Path for file-based session storage. | - |
YAO_SESSION_HOST |
Redis host for session storage. | 127.0.0.1 |
YAO_SESSION_PORT |
Redis port for session storage. | 6379 |
YAO_SESSION_PASSWORD |
Password for Redis session storage. | - |
YAO_SESSION_USERNAME |
Username for Redis session storage. | - |
YAO_SESSION_DB |
Redis database index for session storage. | 1 |
File: documentation/en-us/02-building-your-application/index.mdx
title: Building Your Application
The following sections will guide you in building a simple application with Yao. Before you begin, ensure Yao is installed on your machine and review the sections below for essential background information.
Code Generation Tools
In this example, we use the GPT-4o to demonstrate AI-assisted code creation and show you how to write prompts.
However, you’re free to use any other model you prefer. You can also write the code manually or create your own tools to automate code generation.
If you simply want to learn how to build the application, skip this step and copy the code from the repository into your project.
You can also use the Yao Playground as a code generation tool. It's a simple yao app that can generate code for you, and you can run it locally on your machine.
Visual Studio Code Extensions
To enhance your development experience, we recommend installing the following Visual Studio Code extensions:
to be added...
Reading Guide
By following the steps in the document and working through them, you’ll quickly master how to use Yao.
Once completed, you will have built a simple application with Yao, including a REST API, a web page, and an admin panel.
You can also integrate AI into the admin panel to enhance your application.
Reading Order:
👉 REST API
👉 Web Page
👉 CLI
File: documentation/en-us/03-deploying-your-application/01-automatic-deployment.mdx
title: Automatic Deployment
In this guide, we’ll walk you through setting up a GitHub Actions workflow to automate your application’s deployment.
You can use this workflow to deploy your application to a server with Yao installed or run it in a Docker container.
Prerequisites
Before you begin, make sure you have the following:
- A server with Yao installed or a Docker container running Yao.
- A GitHub repository with your application source code.
- SSH access to the server
Step 1: Add Dockerfile
First, you need to add a Dockerfile to your application. The Dockerfile should look like this:
docker/Dockerfile
FROM yaoapp/yao:0.10.4-amd64
# Add your application files to the container
ADD app /data/app
# Copy the production environment file
RUN cp /data/app/.env.online /data/app/.env
# Change the permissions of the application files:
# /data/app Read-Only (755 should work for directories, files are 444)
# /data/app/data Read-Write
# /data/app/logs Read-Write
# /data/app/db Read-Write
RUN chown -R yao:yao /data/app && \
chmod -R 555 /data/app && \
chmod -R 755 /data/app/data && \
chmod -R 755 /data/app/logs && \
chmod -R 755 /data/app/db
# Declare volumes for persistent data and logs
VOLUME /data/app/data
VOLUME /data/app/logs
VOLUME /data/app/db
# Expose the application port
EXPOSE 5099
# Start the Yao application
CMD ["/usr/local/bin/yao", "start"]Test the Dockerfile by building and running the Docker container locally, make sure it works as expected.
Step 2: Create Workflow
Create a new file in the .github/workflows directory of your repository, name it deploy.yml and add the following content:
name: Deploy
on:
workflow_dispatch:
inputs:
tags:
description: "Version tags"
push:
branches: [main]
env:
VERSION: 0.9.0
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Copy source for distribution
run: |
cp -r . ../dist
rm -rf ../dist/.git
- name: Copy source to docker directory
run: |
cp -r ../dist ./docker/app
- name: Get Version
run: |
echo VERSION=$(cat ./app.yao |grep 'version' | awk -F '"' '{print $4}') >> $GITHUB_ENV
- name: Check Version
run: echo $VERSION
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
registry: your-docker-registry.com
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build Image
uses: docker/build-push-action@v5
with:
context: ./docker
platforms: linux/amd64
push: true
tags: your-docker-registry.com/your-org/your-app:${{ env.VERSION }}-your-tag
- name: Deploy Development
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
# Pull the Docker image
docker pull your-docker-registry.com/your-org/your-app:${{ env.VERSION }}-your-tag
# stop and remove the existing container
docker stop your-app || true
docker rm your-app || true
# Run the Docker container
docker run -d --name your-app \
-v /path/to/host/app/data:/data/app/data \
-v /path/to/host/app/logs:/data/app/logs \
-v /path/to/host/app/db:/data/app/db \
-p 5099:5099 your-docker-registry.com/your-org/your-app:${{ env.VERSION }}-your-tag
# Run migrations and seed data if nessesary
# Run a backup script to backup the database and data, before running the migrations
docker exec your-app sh -c 'yao migrate --force'Step 3: Configure Secrets
To use the workflow, you need to configure the following secrets in your repository:
| Secret Name | Description |
|---|---|
DOCKER_USER |
DockerHub username |
DOCKER_TOKEN |
DockerHub token |
SSH_HOST |
Server hostname |
SSH_PORT |
Server port |
SSH_USER |
Server username, make sure it has docker permissions |
SSH_KEY |
SSH private key |
Step 4: Run Workflow
To deploy your application, go to the Actions tab in your repository and run the Deploy workflow.
The workflow will build the Docker image, push it to your Docker registry, and deploy it to your server.
That's it! Your application is now deployed automatically.
🎉 Congratulations
Your application has been successfully deployed automatically! 🚀
Setting up a CI/CD pipeline is essential to automate deployments and ensure your application stays up-to-date.
File: documentation/en-us/03-deploying-your-application/02-distributed-deployment.mdx
title: Distributed Deployment
To deploy your application to multiple servers, You need to change the app configuration to support distributed deployment.
Session sharing
To enable session sharing between servers, you need to configure your application to use a shared session store.
You can use a Redis server to store session data, then configure your application to use it.
.env
YAO_SESSION_STORE=redis
YAO_SESSION_HOST=your-redis-server-ip
YAO_SESSION_PORT=yout-redis-server-port
YAO_SESSION_PASSWORD=your-redis-server-password
YAO_SESSION_DB=5 # Redis database numberMake sure each server has access to the Redis server and the same session configuration.
Database Connection
If you're using a database, you need to configure the database connection for each server.
.env
YAO_DB_DRIVER=mysql
YAO_DB_PRIMARY="webuser:webpass@tcp(127.0.0.1:3306)/website?charset=utf8mb4&parseTime=True&loc=Local"
YAO_DB_SECONDARY="webuser:webpass@tcp(127.0.0.1:3306)/website?charset=utf8mb4&parseTime=True&loc=Local" # Optional, Read-ReplicaMake sure each server has access to the database server and the same database configuration.
Data Synchronization
If your application writes data to the filesystem, you need to synchronize the data between servers.
or you can use a shared storage solution like NFS, GlusterFS, or AWS EFS to store the data.
.env
YAO_DATA_ROOT=/path/to/shared/storageLoad Balancer
To distribute traffic across multiple servers, you can use a load balancer.
A load balancer evenly distributes incoming requests to various servers using different algorithms such as Round-Robin, Least Connections, or IP Hash.
You can choose between a hardware load balancer or a software-based solution like NGINX, HAProxy, or AWS ELB.
NGINX Configuration
http {
upstream app_servers {
# List of your application servers
server app_server_1_ip:5099;
server app_server_2_ip:5099;
server app_server_3_ip:5099;
# Optional: configure load balancing algorithms
# least_conn; # Least connections method
# ip_hash; # IP hash method for session persistence
}
server {
listen 80; # Port the load balancer will listen on
server_name your-domain.com; # Your domain or IP address
location / {
proxy_pass http://app_servers; # Forward traffic to app servers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}File: documentation/en-us/03-deploying-your-application/03-arm64-device-deployment.mdx
title: ARM64 Device Deployment
To deploy your application on devices with ARM64 architecture, install the ARM64 version of Yao on the target device and upload your application’s source code. Refer to the deployment guide for detailed instructions.
File: documentation/en-us/03-deploying-your-application/index.mdx
title: Deploying Your Application
It’s time to launch your application!
This section will guide you through the deployment process. You can choose to deploy your application to a server with Yao installed or run it in a Docker container.
Overview
For self-hosted deployment, you can choose from the following options:
- 👉 Yao Server: Deploy to a server with Yao installed.
- 👉 Docker Container: Build a Docker image and run it in a container.
We're planning on offering hosting services, but they're not available just yet. Once available, you'll be able to use yao deploy to deploy your application to our cloud service. If you're excited about hosting, let us know! We'll prioritize bringing this feature to you. 🤝 Join us on Discord
Further Reading:
- 👉 Automatic Deployment Deploy your application automatically.
- 👉 Distributed Deployment Deploy your application to multiple servers.
- 👉 ARM64 Device Deployment Deploy your application to devices based on ARM64 architecture.
Yao Server
The Yao server is a server with Yao installed. You can deploy your application to the server and run it.
Step 1: Install Yao
First, you need to install Yao on the server. You can follow the 👉 Installation Guide to install Yao.
Step 2: Upload Your Application
Next, you need to upload your application source code to the server.
cd /path/to/your/application
scp -r . user@server:/path/to/destination❗ Change the permissions of the application files:
Keep the application files read-only and the data, db, and logs directories read-write. This is a good practice for security.
# @ Server
cd /path/to/destination
chown -R [user]:[group] . # Change the owner of the files to the user and group, e.g., webuser:webuser
chmod -R 555 . # Set the files to read-only
chmod -R 755 data # Set the data directory to read-write
chmod -R 755 logs # Set the logs directory to read-write
chmod -R 755 db # Set the db directory to read-writeStep 3: Configure Your Application
Modify the .env file on the server to configure your application. 👉 App Configuration
Example:
YAO_ENV=production
YAO_DB_DRIVER="mysql"
YAO_DB_PRIMARY="webuser:webpass@tcp(127.0.0.1:3306)/website?charset=utf8mb4&parseTime=True&loc=Local"📜 Tips:
- Prepare two env files, one for development and one for production, copy the production env file to the server and rename it to .env
- Use
yao inspectto check the configuration of your application.cd /path/to/your/application && yao inspect - For production use, make sure to set
YAO_ENV=productionin the .env file, It reduces the log output and improves performance.
Step 4: Migration
The first time you deploy your application or data model changes, you need to use the yao migrate command to migrate the database.
yao migrate will detect the changes in the data model and apply them to the database. If you need to reset the database, you can use the --reset flag.
❗Migrate command is a dangerous operation, make sure to backup your database before running it.
cd /path/to/your/application
# Migrate command is a dangerous operation, make sure to backup your database before running it.
yao migrate --forceRun other custom processes to prepare your application, such as seeding data, after the migration is complete, if necessary.
Step 5: Start Your Application
After the migration is complete, you can start your application.
Use nohup to start your application in the background.
# Start your application in the background
# ❗DO NOT run this command under the root user, it should be same as the owner of the application files.
cd /path/to/your/application && nohup yao start >> /path/to/your/application/yao.log 2>&1 &❗Recommended: Use PM2 or a similar process manager to manage the yao start process for improved reliability and uptime.
# ❗DO NOT run this command under the root user, it should be same as the owner of the application files.
cd /path/to/your/application
# start your application with pm2
pm2 start "yao start" --name yao-app
# Check list of running applications
pm2 list
# Check logs
pm2 logs yao-appDocker Container
You can also deploy your application in a Docker container.
Step 1: Build Docker Image
Dockefile:
FROM yaoapp/yao:0.10.4-amd64
# Add your application files to the container
ADD /path/to/your/application /data/app
# Copy the production environment file
RUN cp /data/app/.env.online /data/app/.env
# Change the permissions of the application files:
# /data/app Read-Only (755 should work for directories, files are 444)
# /data/app/data Read-Write
# /data/app/logs Read-Write
# /data/app/db Read-Write
RUN chown -R yao:yao /data/app && \
chmod -R 555 /data/app && \
chmod -R 755 /data/app/data && \
chmod -R 755 /data/app/logs && \
chmod -R 755 /data/app/db
# Declare volumes for persistent data and logs
VOLUME /data/app/data
VOLUME /data/app/logs
VOLUME /data/app/db
# Expose the application port
EXPOSE 5099
# Start the Yao application
CMD ["/usr/local/bin/yao", "start"]Build and push the Docker image:
docker build -t your-registry.com/your-app:version .
# Push the Docker image to your registry
docker push your-registry.com/your-app:versionStep 2: Run Docker Container
# Run the Docker container
docker run -d --name your-app \
-v /path/to/host/app/data:/data/app/data \
-v /path/to/host/app/logs:/data/app/logs \
-v /path/to/host/app/db:/data/app/db \
-p 5099:5099 your-registry.com/your-app:version
# Check the running container
docker ps
# Check logs
docker logs your-app
# Some useful commands
docker exec -it your-app sh # Access the container shell
docker exec your-app sh -c "yao migrate --force" # Migrate the database
docker exec your-app sh -c "yao run [process]" # Run a custom process🎉 Congratulations
Your application is now deployed and running. 🚀
Next, learn how to automate the deployment of your application whenever you push code to the github repository.
File: documentation/en-us/04-references/01-yao-command.mdx
title: Yao Command Reference
The detailed reference for the Yao command.
Available Commands
| Command | Description | Example |
|---|---|---|
| yao start | Start the built-in http server | yao start |
| yao run | Run a process | yao run utils.app.Ping |
| yao migrate | Migrate the database, build the schema | yao migrate |
| yao version | Display the version of Yao | yao version --all |
| yao inspect | Inspect the application configuration | yao inspect |
| yao sui build | Build the SUI page | yao sui build web default |
| yao sui watch | Watch the SUI page changes, and rebuild automatically | yao sui watch web default |
| yao help | Display help information for the Yao command | yao help |
❗ Yao command should be executed in the root directory of the project.
Yao Start
yao start [--debug] [--disable-watching]
Start the built-in http server.
# Start the application server
yao start
# Start the application server in debug mode
yao start --debug
# Start the application server in debug mode and disable watching
yao start --debug --disable-watching
# Display help information for the Yao start command
yao start --helpYao Run
yao run [-s | --silent] [...args]
The yao run command is used to execute a single process. If the argument is an object, use the '::' prefix to pass the object as a string.
# Run a process
yao run utils.app.Ping
yao run models.tests.pet.Find 1 '::{"select": ["id", "name"]}'
yao run scripts.tests.Hello 'Hello, Yao!'
# Run a process in silent mode
yao run --silent utils.app.Ping
yao run --silent models.tests.pet.Find 1 '::{"select": ["id", "name"]}'
yao run -s scripts.tests.Hello 'Hello, Yao!'
# Display help information for the Yao run command
yao run --helpYao Migrate
yao migrate [-n | --name <model_id>] [--reset] [--force]
Migrate the database, build the schema
# Migrate the database, build the schema
yao migrate
# Migrate the database, build the schema and force
yao migrate --force
# Migrate the database, build the schema and reset
yao migrate --reset
# Migrate the database, build the schema and specify the model ID
yao migrate --name models.tests.pet
yao migrate -n models.tests.petYao Version
yao version [--all]
Display the version of Yao
# Display the version of Yao
yao version
# Display the version of Yao and all dependencies
yao version --allYao Inspect
yao inspect
Inspect the application configuration
# Inspect the application configuration
yao inspectYao SUI Build
yao sui build <sui_id> <template_name>
Build the SUI page
yao sui build web defaultYao SUI Watch
yao sui watch <sui_id> <template_name>
Watch the SUI page changes, and rebuild automatically
yao sui watch web defaultYao Help
Display help information for the Yao command
yao helpFile: documentation/en-us/04-references/02-yao-process.mdx
title: Yao Process Reference
A detailed reference to the Yao internal processes.
Note: This document is a work in progress, some links may not work as expected.
Internal Processes
| Documentation | Namespace | Description |
|---|---|---|
| Model | models. |
Interacts with the database to perform CRUD operations on models. |
| Schema | schemas. |
Manages the schema structure and database migrations. |
| Store | stores. |
Provides key-value store operations for storing data. |
| Flow | flows. |
Executes and manages process flows within the application. |
| Schedule | schedules. |
Defines scheduled tasks and periodic executions. |
| Pipe | pipe.* | Provides utility processes for handling data pipes and flows. |
| File System | fs. |
Manages file system interactions, including reading and writing. |
| API | api.* | Utility processes for managing and interacting with APIs. |
| HTTP | http.* | Processes HTTP requests and responses. |
| Session | session.* | Manages user sessions and state information. |
| Encoding | encoding.* | Provides encoding and decoding utilities for various formats. |
| Crypto | crypto.* | Performs cryptographic operations, such as hashing and encryption. |
| SSL | ssl.* | Handles SSL/TLS encryption for secure communications. |
| Utils | utils.* | Provides general utility functions for various tasks. |
| OpenAI | openai.* | Interacts with OpenAI services for AI-powered tasks. |
| MOAPI | moapi.* | Processes related to MOAPI services for integrating APIs. |
| Neo | neo.* | Manages Neo chatbot interactions and AI-driven conversations. |
| AIGC | aigcs.* | Send prompts to the AI Model for generating AI-driven content. |
| SUI | sui.* | Provides utilities for the SUI engine and web page management. |
| Yao App | yao.app.* | Processes for managing the Yao application widget and logic. |
| Yao Login | yao.login.* | Handles user authentication and login processes. |
| Yao Table | yao.table.* | Manages table widget operations, including data binding and CRUD. |
| Yao Form | yao.form.* | Handles form widget operations, including data validation and submission. |
| Yao List | yao.list.* | Manages dashboard widgets and displays list-based data. |
| Yao Chart | yao.chart.* | Manages chart widgets and data visualization in the admin panel. |
| Yao Dashboard | yao.dashboard.* | Manages dashboard widgets for creating custom admin panels. |
| Script | scripts.* | Custom processes written in TypeScript to extend functionality. |
| Plugin | plugins.* | Manages GRPC plugin integration and custom plugin logic. |
File: documentation/en-us/04-references/03-yao-runtime.mdx
title: Yao Runtime APIs
Details of the Yao runtime APIs.
Note: This document is a work in progress, some links may not work as expected.
Runtime APIs
| Documentation | Description |
|---|---|
| Process | Executes a process, similar to the yao run command, to trigger workflows. |
| FS | Manages file system operations such as reading, writing, and modifying files. |
| Store | Provides key-value store operations for efficient data storage and retrieval. |
| Query | Performs database query operations for retrieving and manipulating data. |
| Exception | Defines and manages exceptions for handling errors and custom error messages. |
| http | Handles HTTP requests and responses for communication between services. |
| time | Provides time-based functions like time.After and time.Sleep for delay and scheduling. |
| console | Displays console output in the terminal for debugging and monitoring. |
| log | Manages logging operations for tracking events, errors, and debugging information. |
| atob | Decodes a base64-encoded string to its original form. |
| btoa | Encodes a string to base64 format. |
File: documentation/en-us/04-references/04-yao-dsl.mdx
title: Yao DSL
Details of for the Yao DSL.
Note: This document is a work in progress, some links may not work as expected.
Widget DSLs
| Documentation | Description |
|---|---|
| Model | Describes the data structure (like a database schema), defining columns and CRUD operations. |
| API | Defines REST API endpoints and their methods for interacting with the application. |
| Table | Defines a table widget for displaying and managing data with auto-generated CRUD operations. |
| Form | Describes a form widget for user input, including fields and validation rules. |
| List | A list of data with support for sorting for user input. |
| Chart | Describes a chart widget for visualizing data in various chart formats. |
| Dashboard | Combines widgets (tables, charts, lists) to provide a comprehensive view of data metrics. |
| Connector | Defines connectors for integrating with external services like databases or APIs. |
| Store | Key-value store for managing application state or caching data. |
| Schedule | Defines scheduled tasks for automatic execution at specified intervals. |
| Flow | Defines a sequence of processes or actions in a workflow. |
| Pipe | Manages data flow between processes, often used for chaining actions. |
| AIGC | Leverages AI to generate dynamic content based on prompts or data models. |
| SUI | Template engine for generating web pages. |
File: documentation/en-us/04-references/05-ui-components.mdx
title: UI Components
A complete list of all UI components in Yao DSLs.
Note: This document is a work in progress, some links may not work as expected.
View Components
Components that are used to display data or interact with the user, can be used to Table Widgets.
| Component | Description |
|---|---|
| A | A link that shows a tooltip with the destination URL on hover and opens the link |
| Checkbox | A checkbox for selecting or deselecting an option |
| Color | A color picker for selecting a color |
| Image | An image element for displaying images |
| Switch | A switch for toggling between two states |
| Tag | A tag for categorizing or labeling content |
| Text | A text element for displaying text |
| Tooltip | A tooltip that shows additional information on hover |
Edit Components
Components that are used to edit data or interact with the user, can be used to Form Widget.
| Component | Description |
|---|---|
| Autocomplete | An input field with a dropdown list for selecting an option from a list |
| Cascader | A cascading dropdown list for selecting an option from a hierarchy |
| CheckboxGroup | A group of checkboxes for selecting multiple options |
| CodeEditor | A code editor for editing code |
| ColorPicker | A color picker for selecting a color |
| Divider | A horizontal line to separate content |
| FlowBuilder | A flow builder for creating workflows |
| FormBuilder | A form builder for creating forms |
| Frame | A frame for displaying content in a bordered box |
| Input | An input field for entering text |
| InputNumber | An input field for entering numbers |
| List | A list for displaying data |
| Password | An input field for entering passwords |
| Placement | A placement for positioning elements |
| Select | A dropdown list for selecting an option from a list |
| TextArea | A text area for entering multiple lines of text |
| Text | A text element for displaying text |
| TimePicker | A time picker for selecting a time |
| Tree | A tree for displaying hierarchical data |
| Upload | An upload component for uploading files |
| WangEditor | A WYSIWYG editor for editing text |
| Table | A table reference for displaying data |
Chart Components
Components that are used to visualize data in various chart formats, can be used to Chart and Dashboard widgets.
| Component | Description |
|---|---|
| Bar | A bar chart |
| Line | A line chart |
| Funnel | A funnel chart |
| LineBar | A line and bar chart |
| Number | A number chart |
| NumberChart | A number chart with a title and value |
| Pie | A pie chart |
| Table | A table display in chart format |
File: documentation/en-us/04-references/06-query-dsl.mdx
title: Query DSL
Yao Query DSL is used to query data from the database or other data sources. It is a powerful tool for filtering, sorting, and aggregating data to get the desired results.
Note: This document is a work in progress, some links may not work as expected.
{
"from": "pets",
"debug": true,
"select": [
"category_id",
"category.category_name",
":COUNT(pets.id) as total"
],
"joins": [
{
"left": true,
"from": "pet_categories as category",
"key": "category_id",
"foreign": "category.id"
}
],
"wheres": [
{ "field": "pets.created_at", ">=": "from" },
{ "field": "pets.created_at", "<=": "to" }
],
"groups": ["category_id"]
}Table of Contents
| Section | Description |
|---|---|
| Overview | An introduction to the Query DSL and its purpose. |
| Basics Usage | Basic usage of the Query DSL. |
| Select | Selecting fields from the data source. |
| Wheres | Filtering data based on conditions. |
| Joins | Joining multiple tables to get related data. |
| Groups | Grouping data based on fields. |
| Orders | Sorting data based on fields. |
| Limits | Limiting the number of records returned. |
| Subqueries | Using subqueries to get data from nested queries. |
| Unions | Combining multiple queries into a single result. |
File: documentation/en-us/04-references/07-template-engine.mdx
title: Template Engine
SUI Template Engine, a new feature in Yao v0.10.4, is AI-friendly and streamlines web page creation and data integration. It supports backward compatibility, enabling developers to use HTML, CSS, and TypeScript/JavaScript while promoting code reusability with a component-based architecture.
Note: This document is a work in progress, some links may not work as expected.
Note: SUI is a new feature and still experimental. For advanced frontend requirements, consider using frameworks like React or Vue. Place the built files in the public directory and connect them to Yao via REST API.
Table of Contents
| Section | Description |
|---|---|
| Overview | An introduction to the Template Engine and its purpose. |
| Template | Introduction to the SUI template for defining the structure of a web page. |
| Document | Defining a new SUI document for displaying content. |
| Assets | Managing assets like images, CSS, and JavaScript files. |
| Global Data | Managing global data for SUI templates. |
| Page | Introduction to the SUI page for defining the layout of a web page. |
| Template Syntax | The syntax for writing SUI templates. Variables, expressions, loops, conditions, and more. |
| Page as a Component | Using components to build reusable UI elements. |
| Component Communication | Communicating between components in SUI templates. |
| Partial Rendering | Rendering a part of the SUI template instead of the whole page. |
| Libsui | The fontend library for rendering SUI templates. |
| Event Handling | Handling events in SUI templates. |
| Backend Script | Writing backend scripts for data integration. |
| SUI Request | Making requests to the backend for data retrieval. |
| Cache Control | Managing cache for SUI templates. |
| I18n | Internationalization and localization for SUI templates. |
| TailwindCSS Integration | Integrating Tailwind CSS for styling SUI templates. |
File: documentation/en-us/04-references/index.mdx
title: References
Here, you can find all the references for Yao. Each reference is a detailed guide on a specific topic. If you can't find what you are looking for, please let us know.
Table of Contents
| Reference | Description | Link |
|---|---|---|
| Yao Command | A complete list of all commands available in the Yao CLI, along with their descriptions. | 👉 Yao Command |
| Yao Process | A detailed list of all Yao internal processes and their descriptions. | 👉 Yao Processes |
| Yao Runtime | A complete list of all Yao runtime APIs along with their descriptions. | 👉 Yao Runtime |
| Yao DSL | A complete list of all Yao Widget DSLs and their descriptions. | 👉 Yao DSL |
| Query DSL | A detailed list of all database Query DSLs with their descriptions. | 👉 Query DSL |
| UI Components | A complete list of all UI components in Yao DSL with their descriptions. | 👉 UI Components |
| Template Engine | A detailed list of all template engine APIs with their descriptions. | 👉 Template Engine |
File: documentation/en-us/05-using-source-code/01-compiling-source-code.mdx
title: Compiling Source Code
This section walks you through compiling the source code and running it locally.
The guide uses Ubuntu 23.04 LTS as the reference operating system.
Step 1: Clone the Repositories
To compile the source code, you need to clone the repositories to your local machine. Here are the repositories you need to clone:
mkdir -p /your/directory && \
git clone https://github.com/yaoapp/kun.git /your/directory/kun && \
git clone https://github.com/yaoapp/xun.git /your/directory/xun && \
git clone https://github.com/yaoapp/gou.git /your/directory/gou && \
git clone https://github.com/yaoapp/v8go.git /your/directory/v8go && \
git clone https://github.com/yaoapp/xgen.git /your/directory/xgen-v1.0 && \
git clone https://github.com/yaoapp/yao-init.git /your/directory/yao-init && \
git clone https://github.com/yaoapp/yao.git /your/directory/yaoUnzip libv8 zip
cd /your/directory
files=$(find /app/v8go -name "libv8*.zip")
for file in $files; do
dir=$(dirname "$file") # Get the directory where the ZIP file is located
echo "Extracting $file to directory $dir"
unzip -o -d $dir $file
rm -rf $dir/__MACOSX
doneStep 2: Install the Dependencies
# Install dependencies for building the source code
apt-get update && \
apt-get install -y libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi libncurses5-dev build-essential bison flex libssl-dev bc && \
apt-get install -y gcc-arm-linux-gnueabi g++-arm-linux-gnueabi && \
apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf && \
apt-get install -y g++-aarch64-linux-gnu crossbuild-essential-arm64 && \
apt-get install -y gcc-13-aarch64-linux-gnu && \
apt-get install -y g++-13-aarch64-linux-gnu && \
apt-get install -y wget && \
apt-get install -y curl && \
apt-get install -y git && \
apt-get install -y unzip
# Golang
wget https://golang.org/dl/go1.21.1.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go1.21.1.linux-amd64.tar.gz && \
rm go1.21.1.linux-amd64.tar.gz
# Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
apt-get install -y nodejs
# PNPM
npm install -g pnpmStep 3: Build the Binaries
After cloning the repositories, you need to build the binaries. Here's how you can do it:
cd /your/directory/yao && \
export VERSION=$(cat share/const.go |grep 'const VERSION' | awk '{print $4}' | sed "s/\"//g")
cd /your/directory/yao && make tools && make artifacts-linux
ls -l /your/directory/yao/dist/releaseRunning the Source Code Locally
cd /your/directory/yao
go run . run utils.app.PingFile: documentation/en-us/05-using-source-code/02-adding-your-process.mdx
title: Adding Your Process
This section guides you through adding a custom process to Yao. You can run it using yao run or invoke it via the Process API.
Step 1: Create a New Process
# Create a new process file
mkdir -p /code/root/yao/hello
touch /code/root/yao/hello/hello.go// /code/root/yao/hello/hello.go
package hello
import (
"github.com/yaoapp/gou/process"
)
func init(){
process.Register("namespace.hello", processHello)
}
func processHello(process *process.Process) inteface{} {
args := process.Args
return map[string]interface{}{"args": process.Args}
}Step 2: main.go
Import the new process into the main.go file.
package main
import (
"github.com/yaoapp/yao/cmd"
"github.com/yaoapp/yao/utils"
// Import the new process
_ "github.com/yaoapp/yao/hello"
_ "github.com/yaoapp/gou/encoding"
_ "github.com/yaoapp/yao/aigc"
_ "github.com/yaoapp/yao/crypto"
_ "github.com/yaoapp/yao/helper"
_ "github.com/yaoapp/yao/openai"
_ "github.com/yaoapp/yao/wework"
)File: documentation/en-us/05-using-source-code/03-adding-your-component.mdx
title: Adding Your Component
This section guides you through adding a custom component to Yao. You can use it in your application to create custom interfaces and widgets.
Step 1: Clone the XGEN Repository
To add a custom component, you need to clone the XGEN repository to your local machine. XGEN is the default interface engine for building admin panels in Yao.
# Clone the XGEN repository
git clone https://github.com/yaoapp/xgen.git /your/directory/xgenStep 2: Run the XGEN development
You need start the yao http server, it's the backend server for the xgen development server.
cd /path/to/your/project
yao startThen you can start the xgen development server.
cd /your/directory/xgen
pnpm install
pnpm devThrough the xgen dev server to visit admin panel.
Step 3: Create a New Component
Reference the Input component code to implement your own component. Place the component in the packages/xgen/components/edit folder.
👉 packages/xgen/components/edit/Input
// packages/xgen/components/edit/YourComponent/index.tsx
import { Input } from "antd";
import { Item } from "@/components";
import { getLocale } from "@umijs/max";
import type { InputProps } from "antd";
import type { Component } from "@/types";
interface IProps extends InputProps, Component.PropsEditComponent {}
const Index = (props: IProps) => {
const { __bind, __name, itemProps, ...rest_props } = props;
const is_cn = getLocale() === "zh-CN";
return (
<Item {...itemProps} {...{ __bind, __name }}>
<Input
placeholder={`Please input .... ${__name}`}
{...rest_props}
></Input>
</Item>
);
};
export default window.$app.memo(Index);Step 4: Use the Component
// ...
{
"edit": {
"type": "YourComponent",
"props": {
// ...
}
}
}
// ...Step 5: Build the Component Library
To build the component library, you need to run the following command:
cd /your/directory/xgen
pnpm buildAfter building the component library, place the compiled files in the public directory, or host them on a CDN.
File: documentation/en-us/05-using-source-code/04-building-your-component-library.mdx
title: Building Your Component Library
This section guides you through creating a custom component library tailored to your business needs.
With Yao as the backend and XGEN as the frontend, you can fork the XGEN repository and start building your library.
File: documentation/en-us/05-using-source-code/index.mdx
title: Using Source Code
This section guides you through using source code to add processes, add components, and build a custom component library tailored to your business needs.
The Repositories
Yao is primarily developed using Golang, with the default interface engine, XGEN, built using the React framework.
It separates several repositories for different purposes:
| Repository | Description | Link |
|---|---|---|
| YaoApp/Yao | Core Yao repository. Defines the command-line tool & internal processes. | 👉 YaoApp/yao |
| YaoApp/Gou | App engine framework. | 👉 YaoApp/gou |
| YaoApp/Xun | Database ORM. | 👉 YaoApp/xun |
| YaoApp/Kun | Utility structures and functions. | 👉 YaoApp/kun |
| YaoApp/Xgen | Default UI engine for building admin panels. Integrated into Yao executable. | 👉 YaoApp/Xgen |
Yao uses the rogchap/v8go package to execute JavaScript code within the Go runtime. For our specific needs, we've forked the v8go package and added custom features to better support our requirements.
You can access the forked repository here 👉 YaoApp/v8go
How to Use Source Code
To use the source code, you need to clone the repositories and build the binaries, build it, and run it on your local machine.
Here's how you can do it:
👉 Building Your Component Library
File: documentation/en-us/06-community/01-contribution-guide.mdx
title: Contribution Guide
Thank you for considering contributing to Yao! We welcome all contributions, big or small, and appreciate your help in making Yao even better. 🚀
Improve Documentation
Yao's documentation is still a work in progress, and we’d love your help in making it more complete and accurate. If you spot any errors, typos, or areas where more information is needed, your contributions will make a big difference! Simply submit a pull request and help us improve it for everyone.
The documentation is hosted on GitHub, and you can find the repository here:
👉 Yao Docs
Bug Reports
Yao has redefined many aspects of web application development, and the work involved is massive. While we’ve made great strides, there are bound to be bugs and areas that can still be improved and optimized. If you come across any issues, please help us identify them by reporting bugs so we can continue improving Yao.
Your feedback is essential in making Yao even better!
Feature Requests
Got a great idea for a new feature or an improvement? We'd love to hear it! Share your suggestions with the community and discuss them with us. Your input plays a key role in shaping the future of Yao, making it more powerful and user-friendly for everyone.
Contribute Code
If you’re a developer, there’s a lot you can do to help Yao grow! Whether it’s writing code, fixing bugs, or implementing new features, your contributions will directly impact Yao’s future and make it even more powerful and versatile.
To get started, check out our guide on Using Source Code and learn how to build your own component library to contribute.
Your code can make a big difference—join us in building something amazing!
File: documentation/en-us/06-community/index.mdx
title: Yao Community
Welcome to the Yao Community, where developers like you come together to collaborate, share ideas, and make Yao even better! 🚀
Although it has been three years since Yao’s initial release, we intentionally kept it within a niche circle before version 0.10.4. During that time, our focus was on refining and perfecting the product. Now, we’re ready to open up and invite more developers to join the community and help shape the future of Yao.
After releasing v0.10.4, we launched our official Discord channel to create a space for discussion and feedback—come join us, share your experiences, and help grow the community!
How to Contribute
There are many exciting ways to get involved in the Yao community—your contributions, big or small, make a huge difference:
📚 Improve Documentation
Help make Yao's documentation better and more comprehensive by submitting pull requests.🐞 Report Bugs
Found a bug? Let us know! Your feedback helps us fix issues and improve Yao.💡 Request Features
Have a great idea for a new feature? Share it with the community and discuss it with us.💻 Contribute Code
Write code, fix bugs, or implement features—your coding skills can help shape Yao's future.
Join us today and be part of an amazing journey to build and grow Yao together! ❤️
File: documentation/ja-jp/README.md
Yao 公式ドキュメント
File: documentation/zh-cn/README.md
Yao 官方文档
File: documentation/zh-cn/01-getting-started/01-switching-to-yao.mdx
[Binary file]
File: documentation/zh-cn/01-getting-started/02-installation.mdx
title: 安装
related:
title: 下一步
links:
- building-your-application
Yao 是一个独立的可执行文件,不依赖于任何包或工具链。只需下载并运行它即可开始构建你的应用程序。每台机器或服务器只需安装一次。
安装
运行以下命令在你的机器或服务器上安装 Yao。
Linux 和 macOS
curl -fsSL https://yaoapps.com/install.sh | bash👉 查看安装脚本
Windows
要在 Windows 上安装 Yao,你需要安装 WSL2。如果你还没有安装 WSL2,可以按照官方指南进行安装。
powershell -c "irm yaoapps.com/install.ps1 | iex"👉 查看安装脚本
Docker
Yao 提供生产和开发用 Docker 镜像,支持 x64 和 arm64 架构。
开发镜像包含额外的开发工具和库,基于 Ubuntu 22.04,而生产镜像更小,基于 Alpine 3.14。
下载最新的生产镜像:
docker pull yaoapp/yao:latest
# 或指定版本
docker pull yaoapp/yao:0.10.4下载最新的开发镜像:
docker pull yaoapp/yao:0.10.4-dev检查安装
安装 Yao 后,你可以通过运行以下命令检查版本:
yao version --all如果出现错误,请验证 yao 命令是否在你系统的 PATH 中。
如果找不到,你可能需要将包含 yao 可执行文件的目录添加到你的 PATH 中,并确保它具有执行权限。
下载开发版本
Yao 正在积极开发中,你可以下载最新的开发版本来尝试新功能和改进。
对于 Windows,你可以下载 Linux 版本并在 WSL2 中运行。
Linux 构建产物
👉 https://github.com/YaoApp/yao/actions/workflows/build-linux.yml
在上述页面中,选择最新的构建,下载并解压,然后选择适合你 CPU 架构的构建产物文件。支持的架构有 x64 和 arm64。
MacOS 构建产物
👉 https://github.com/YaoApp/yao/actions/workflows/build-macos.yml
在上述页面中,选择最新的构建,下载并解压,然后选择适合你 CPU 架构的构建产物文件。支持的架构有 Intel CPU 和 M1/M2/M3/M4 (arm64)
File: documentation/zh-cn/01-getting-started/03-why-yao.mdx
[Binary file]
File: documentation/zh-cn/01-getting-started/index.mdx
[Binary file]
File: documentation/zh-cn/02-building-your-application/01-yao-command.mdx
title: Yao 命令
related:
title: 下一步
links:
- debug-guide
Yao 是一个独立的可执行文件。即使你有多个项目,每台机器或服务器也只需要安装一次。
本节介绍基本的 Yao 命令,这些命令将在后面用于构建一个简单的应用程序。快速浏览一下就足够了。
有关更详细的信息,请参阅 Yao 命令参考。
👉 Yao 命令参考
概述
Yao 命令的基本用法:
| 命令 | 描述 | 示例 |
|---|---|---|
yao start |
启动应用服务器 | yao start |
yao run |
运行一个进程 | yao run utils.app.Ping |
yao migrate |
迁移数据库,构建架构 | yao migrate |
yao version |
显示 Yao 的版本 | yao version --all |
SUI 命令,用于网页构建:
| 命令 | 描述 | 示例 |
|---|---|---|
yao sui build |
构建 SUI 页面 | yao sui build web default |
yao sui watch |
监视 SUI 页面变化,并自动重新构建 | yao sui watch web default |
File: documentation/zh-cn/02-building-your-application/02-debug-guide.mdx
title: 调试指南
related:
title: 下一步
links:
- data-model
本节提供了 Yao 中常见调试方法的快速概述。简单浏览一下就足够了,因为这些方法将在后面构建简单应用程序时使用。
运行进程
yao run 命令用于执行单个进程。这对于调试自定义进程很有用。
你可以执行单个进程来在控制台中显示结果。
注意:
- 进程在服务器端运行。
- 控制台输出显示在终端中,而不是浏览器中。
yao run utils.app.Ping # 返回 Yao 版本信息
yao run models.tests.pet.Find 1 '::{}' # 返回 id 为 1 的宠物信息
yao run not.exist.Process # 返回错误信息打印调试信息
对于调试进程,你可以在脚本中使用 console.log 或 log 对象来输出调试信息。
更多信息,请参阅运行时参考。 👉 运行时参考
yao run scripts.test.Hello 'Yao!' # 返回 'Hello, Yao!'
yao run scripts.test.Pets cat # 返回猫类别的宠物列表scripts/hello.ts
import { Process, log } from "@yao/runtime";
/**
* 向某人问好
*/
function Hello(name: string): string {
// 输出调试信息到控制台
console.log(`Hello, ${name}!`);
// 输出调试信息到日志
log.Debug(`Hello %s`, name);
return `Hello, ${name}!`;
}
/**
* 按类别获取宠物
*/
function Pets(category?: string): Record {
category = category || "dog";
// 执行 models.* 内部进程,按类别获取宠物
const pets = Process("models.tests.pet.Get", {
select: ["id", "name"],
wheres: [{ column: "category", value: category }],
});
// 输出调试信息到控制台
console.Debug(`category: ${category}, pets:`, pets);
// 输出调试信息到日志
log.Info(`category: %s, pets: %#v`, category, pets);
return pets;
}检查日志
默认的应用程序日志存储在 logs 目录中。你可以查看日志文件以获取更详细的信息。
你可以在环境变量中更改日志位置和级别。
更多信息,请参阅应用程序配置部分。
👉 应用程序配置
File: documentation/zh-cn/02-building-your-application/03-data-model.mdx
title: 数据模型
related:
title: 下一步
links:
- rest-api
从本节开始,我们将一起构建一个简单的宠物商店应用程序,演示如何有效地使用 Yao。你将学习如何:
- 🟠 在应用程序中创建和管理数据。
- ⚪ 开发 RESTful API 来暴露数据。 👉 REST API
- ⚪ 设计网页来显示数据。 👉 Web Page
- ⚪ 构建管理面板帮助宠物商店的管理员管理数据。 👉 Admin Panel
- ⚪ 创建后端命令用于任务调度。 👉 CLI
- ⚪ 集成 AI 用于聊天机器人、图像生成和增强用户输入。 👉 AI Integration
确保你已阅读了之前的文档,以理解 Yao 的基本概念。
👉 构建你的应用程序
👉 切换到 Yao
概述
数据模型是定义数据结构的蓝图,是 Yao 应用程序中最重要的部分。
在 Yao 中,数据模型是一个使用 Model DSL 来描述数据结构的部件,类似于数据库架构。理解数据库结构和关系将帮助你有效地设计数据模型。
数据将存储在数据库中。默认情况下,Yao 使用 SQLite 作为数据库引擎。你可以通过修改环境配置来更改数据库引擎为 MySQL 或其他数据库。 👉 应用配置
有关 Model DSL 的更多详细信息,请参阅 👉 DSL 参考
步骤 1:规划数据结构
在创建数据模型之前,你应该规划数据的结构。最好的方式是让 AI 聊天机器人协助你。
打开 AI 聊天机器人并寻求帮助来为你的应用程序生成数据结构。
💬 规划数据结构的提示
这是与 AI 聊天机器人规划宠物商店应用程序数据结构的对话示例。根据你的需求更改提示。
- 我想创建一个宠物商店应用程序。
- 功能包括添加、更新和删除商店中的宠物、宠物类别和商品。
- 帮我设计数据结构,请提供数据表及其字段的列表。
- 请用表名、字段名和字段类型回复我。
- 表名和字段名应该使用 snake_case,自增字段应命名为 `id`,用代码块包裹。
- 例如:
```plaintext
Table: pet_categories
- id: INT PRIMARY KEY AUTO_INCREMENT
- category_name: VARCHAR(255) NOT NULL
- description: TEXT
```🤖 _AI 聊天机器人的回复_
Table: pet_categories
- id: INT PRIMARY KEY AUTO_INCREMENT
- category_name: VARCHAR(255) NOT NULL
- description: TEXT
Table: pets
- id: INT PRIMARY KEY AUTO_INCREMENT
- pet_name: VARCHAR(255) NOT NULL
- category_id: INT NOT NULL
- age: INT
- breed: VARCHAR(255)
- description: TEXT
- FOREIGN KEY (category_id) REFERENCES pet_categories(id)
Table: goods
- id: INT PRIMARY KEY AUTO_INCREMENT
- good_name: VARCHAR(255) NOT NULL
- category_id: INT NOT NULL
- price: DECIMAL(10, 2) NOT NULL
- stock_quantity: INT NOT NULL
- description: TEXT
- FOREIGN KEY (category_id) REFERENCES pet_categories(id)
Table: transactions
- id: INT PRIMARY KEY AUTO_INCREMENT
- pet_id: INT
- good_id: INT
- transaction_date: DATETIME NOT NULL
- quantity: INT NOT NULL
- total_price: DECIMAL(10, 2) NOT NULL
- FOREIGN KEY (pet_id) REFERENCES pets(id)
- FOREIGN KEY (good_id) REFERENCES goods(id)
说明:
pet_categories:此表存储商店中可用的各种宠物和商品类别。
pets:此表跟踪商店中可用的宠物,包括它们的名称、年龄、品种和类别。
goods:此表记录可供购买的商品,包括它们的名称、价格、库存数量和关联类别。
transactions:此表记录涉及宠物和商品的交易,包括日期、数量和总价。步骤 2:生成 Model DSL
在规划好数据结构后,你现在可以为你的应用程序生成 Model DSL。
将你的数据结构和一个或多个现有的 Model DSL 示例发送给聊天机器人,并请求帮助生成类似的 Model DSL。
你可以从 Yao 文档或其他公共仓库获取现有的 Model DSL 示例。在本例中,我们将使用 Yao 网站仓库中的文章模型。
💬 生成 Model DSL 的提示
这是与 AI 聊天机器人生成宠物商店应用程序 Model DSL 的对话示例。根据你的需求更改提示。
Model DSL 示例:
[Model DSL 示例]
已规划的结构:
[已规划的结构(AI 聊天机器人在上一步的回复)]
- 根据已规划的结构,我需要帮助为宠物商店应用程序生成 Model DSL。
- 请按照提供的示例提供 Model DSL。
- 每个 Model DSL 应该用代码块包裹。🤖 _AI 聊天机器人的回复_
AI 聊天机器人将根据提供的结构为每个表生成 Model DSL。
看起来像这样:
// pet_categories 的 Model DSL
{
"name": "PetCategory",
"table": { "name": "pet_categories", "comment": "Pet Categories" },
"columns": [
{ "name": "id", "comment": "ID", "type": "ID", "label": "ID" },
{
"label": "Category Name",
"name": "category_name",
"comment": "Name of the pet category",
"type": "string",
"length": 255,
"nullable": false
},
{
"label": "Description",
"name": "description",
"comment": "Description of the pet category",
"type": "text",
"nullable": true
}
],
"option": { "timestamps": true }
}
// ....📝 注意:
你可以改进提示并直接生成 Model DSL。在本例中,步骤被分开是为了更好地理解。
💬 直接生成 Model DSL 的提示
按照以下提示,你可以直接生成 Model DSL。
Model DSL 示例:
[Model DSL 示例]
- 我想创建一个宠物商店应用程序。
- 功能包括添加、更新和删除商店中的宠物、宠物类别和商品。
- 帮我设计宠物商店应用程序的数据结构。
- 根据规划的结构,我需要帮助为宠物商店应用程序生成 Model DSL。
- 请按照提供的示例提供 Model DSL。
- 每个 Model DSL 应该用代码块包裹。🪄 添加更多提示
添加更多提示有助于生成更好的 Model DSL。你提供的信息越多,AI 聊天机器人就越能理解你的需求。
例如,向 AI 聊天机器人描述你的业务,它将为你生成更适合的 Model DSL。
你还可以建立一些编码标准,以便于未来的开发和维护工作。
步骤 3:保存 Model DSL
在继续之前,确保你已经查看了之前的文档以了解 Yao 应用程序的目录结构,并已使用快速入门指南创建了一个 Yao 应用程序。
👉 快速开始
👉 Yao 应用程序
💾 保存到 Models 目录
生成 Model DSL 后,将 JSON 部分保存在 Yao 应用程序的 models 目录中。确保文件和目录名称使用小写并具有 .mod.yao 扩展名。你可以使用子目录进一步组织它们。
例如:
- 将
petsModel DSL 保存为models/pets.mod.yao,部件 ID 为pets。 - 将
pet_categoriesModel DSL 保存为models/pet/categories.mod.yao,部件 ID 为pet.categories。
部件 ID 对于进程引用很重要,用 . 替换 /。例如,models.pet.Find 或 models.pet.categories.Find。
保存后,models 目录应该看起来像这样:
└── models
├── goods.mod.yao
├── pet
│ └── categories.mod.yao
├── pets.mod.yao
└── transactions.mod.yao你可以在演示应用程序仓库中找到它们。 👉 演示应用程序
📝 注意:
为了维护 Model DSL,建议保持 Model DSL 名称与表名一致。这将帮助你轻松识别每个表的 Model DSL。
表名在 Model DSL 中定义。表名应该使用 snake_case,字段名也应如此,并且都必须全部使用小写。这是 Yao 的严格要求,以确保跨平台文件系统的兼容性。
例如:
{
"name": "Pet Categories",
// 表名是数据库中的表名
"table": { "name": "pet_categories", "comment": "Pet Categories" },
"columns": [{ "name": "id", "comment": "ID", "type": "ID", "label": "ID" }]
}- 保存在
models/pet/categories.mod.yao的pet_categories表将有一个部件 IDpet.categories。 - 保存在
models/pets.mod.yao的pets表将有一个部件 IDpets。
步骤 4:创建数据库表
一旦保存了 Model DSL,你可以使用 yao migrate 命令根据 Model DSL 创建数据库表。
📺 Yao Migrate 命令
进入项目根目录并运行 yao migrate 命令。这将根据 models 目录中的 Model DSL 创建数据库表。
如果你已经完成这个步骤并需要重置数据库,你可以使用 --reset 标志运行 yao migrate。
yao migrate 命令仅用于开发和测试环境。如果你需要在生产环境中使用它,必须包含 --force 标志来执行它。这是一个危险的操作,所以要谨慎进行。
你可以通过设置 YAO_ENV 环境变量在开发和生产模式之间切换。更多详细信息,请参阅 👉 应用配置
# 进入项目根目录,
# 如果你的机器上有多个项目,确保你在正确的项目目录中。
cd /path/to/your/project
# 一次性迁移所有模型
# 根据 Model DSL 创建数据库表。如果表已存在,将会被修改。
yao migrate
# 使用 --reset 标志一次性迁移所有模型
# 重置数据库表。这将删除现有表并重新创建它们。
yao migrate --reset
# 一次迁移一个模型
# 根据特定模型的 Model DSL 创建数据库表。
# 参数是模型的部件 ID。例如:pets, pet.categories
yao migrate --name pets
# 使用 --reset 标志一次迁移一个模型
# 重置特定模型的数据库表。
# 参数是模型的部件 ID。例如:pets, pet.categories
yao migrate --name pets --reset
# 对于生产环境,使用 --force 标志。
yao migrate --force运行 yao migrate 命令后,检查终端中的结果。
AI 偶尔会犯错,如果有任何错误,向 AI 聊天机器人报告以寻求帮助,根据需要更新 Model DSL,并重复直到成功。
正确的输出应该看起来像这样:
Update schema model: goods (goods) SUCCESS
Update schema model: pet.categories (pet_categories) SUCCESS
Update schema model: pets (pets) SUCCESS
Update schema model: transactions (transactions) SUCCESS✅ 检查数据库表
在本例中,成功运行后 sqlite 数据库文件将在你的 Yao 应用程序的 db 目录中创建。
如果你想使用不同的数据库引擎,可以修改环境配置。 👉 应用配置
你可以使用数据库管理工具来检查数据库表,比如 DB Browser for SQLite、DBeaver 或任何你喜欢的工具。
步骤 5:准备测试数据(可选)
准备测试数据并设置自定义进程来导入它是提高开发效率的好做法。
创建数据库表后,你可以根据 Model DSL 为每个表生成测试数据。
将 Model DSL 发送给 AI 聊天机器人,并请求帮助为每个表生成测试数据。然后,使用 yao run 命令执行 models.* 内部进程来导入测试数据。
💬 生成测试数据的提示
这是与 AI 聊天机器人为宠物商店应用程序生成 Model DSL 的对话示例。根据你的需求更改提示。
Model DSL:
[Model DSL]
- 我已经根据 Model DSL 创建了数据库表。
- 我需要帮助为每个表生成测试数据。
- 请为每个表提供测试数据。
- 我将使用 **yao run** 命令导入测试数据。
- 命令是 **yao run models.<WIDGET_ID>.Insert '::["field_name_1","field_name_2",...]' '::[[field_1_value, field_2_value, ...],[field_1_value, field_2_value, ...]]'**。
- "::" 用于将 JSON 字符串作为参数传递。
- WIDGET_ID 是模型的部件 ID。它是从 Model DSL 中的表名命名的。表名 pet_categories 的部件 ID 是 pet.categories,表名 pets 的部件 ID 是 pets。
- 不要包含 ID 字段在测试数据中。
- 注意外键字段应该是有效的。
- 每个表应该至少有 3 条记录。🤖 _AI 聊天机器人的回复_
AI 聊天机器人将生成测试数据,回复看起来像这样:
# Pet Categories
yao run models.pet.categories.Insert '::["category_name","description"]' '::[
["Dogs", "Domesticated carnivorous mammals that typically have a long snout and barking voice."],
["Cats", "Small domesticated carnivorous mammals with soft fur and retractable claws."],
["Birds", "Warm-blooded egg-laying vertebrates characterized by feathers and wings."]
]'
# pets
yao run models.pets.Insert '::["pet_name","category_id","age","breed","description"]' '::[
["Buddy", 1, 3, "Golden Retriever", "Friendly and energetic dog."],
["Whiskers", 2, 2, "Siamese", "Curious and playful cat."],
["Tweety", 3, 1, "Canary", "Bright yellow songbird."]
]'
# ....📺 导入测试数据
生成测试数据后,你可以使用 yao run 命令将测试数据导入数据库表。
yao run 命令用于执行单个进程。这对于调试自定义进程很有用。你可以在 👉 调试指南 中找到如何使用它。
复制生成的 yao run 命令并粘贴到终端中执行。
# 进入项目根目录,
# 如果你的机器上有多个项目,确保你在正确的项目目录中。
cd /path/to/your/project
# 运行 yao run 命令导入测试数据
yao run models.pets.Insert '::["pet_name","category_id","age","breed","description"]' '::[
["Buddy", 1, 3, "Golden Retriever", "Friendly and energetic dog."],
["Whiskers", 2, 2, "Siamese", "Curious and playful cat."],
["Tweety", 3, 1, "Canary", "Bright yellow songbird."]
]'
# ....正确的输出应该看起来像这样:
Run: models.pet.categories.Insert
args[0]: ["category_name","description"]
args[1]: [
["Dogs", "Domesticated carnivorous mammals that typically have a long snout and barking voice."],
["Cats", "Small domesticated carnivorous mammals with soft fur and retractable claws."],
["Birds", "Warm-blooded egg-laying vertebrates characterized by feathers and wings."]
]
--------------------------------------
models.pet.categories.Insert Response
--------------------------------------
null
--------------------------------------
✨DONE✨如果有任何错误,向 AI 聊天机器人报告以寻求帮助,根据需要更新测试数据,并重复直到成功。
✅ 检查导入的数据
导入测试数据后,你可以使用 yao run 来查询数据并检查是否正确导入。当然,你也可以使用数据库管理工具来检查数据。
# 进入项目根目录,
# 如果你的机器上有多个项目,确保你在正确的项目目录中。
cd /path/to/your/project
# 运行 yao run 命令查询数据
yao run models.pets.Get '::{}'正确的输出应该看起来像这样:
Run: models.pets.Get
args[0]: {}
--------------------------------------
models.pets.Get Response
--------------------------------------
[
{
"age": 3,
"breed": "Golden Retriever",
"category_id": 1,
"created_at": "2024-11-18 10:39:51",
"description": "Friendly and energetic dog.",
"id": 1,
"pet_name": "Buddy",
"updated_at": null
},
{
"age": 2,
"breed": "Siamese",
"category_id": 2,
"created_at": "2024-11-18 10:39:51",
"description": "Curious and playful cat.",
"id": 2,
"pet_name": "Whiskers",
"updated_at": null
},
{
"age": 1,
"breed": "Canary",
"category_id": 3,
"created_at": "2024-11-18 10:39:51",
"description": "Bright yellow songbird.",
"id": 3,
"pet_name": "Tweety",
"updated_at": null
}
]
--------------------------------------
✨DONE✨🎉 恭喜
你已经成功为你的宠物商店应用程序创建了数据模型。这包括演示了 Yao 的基本操作:创建数据库表、导入测试数据和查询数据。
接下来,你将学习如何开发 RESTful API 来暴露数据。
- 🟢 在应用程序中创建和管理数据。
- 🔵 开发 RESTful API 来暴露数据。 👉 REST API
- ⚪ 设计网页来显示数据。 👉 Web Page
- ⚪ 构建管理面板帮助宠物商店的管理员管理数据。 👉 Admin Panel
- ⚪ 创建后端命令用于任务调度。 👉 CLI
- ⚪ 集成 AI 用于聊天机器人、图像生成和增强用户输入。 👉 AI Integration
有关数据模型的更多信息,请查看 👉 DSL 参考
在本节中,所有内容都可以由 AI 聊天机器人生成。你可以创建一个 AI 代理或工具,使用自然语言进行自动生成。如果你对构建这样的工具感兴趣,请参阅以下资源:
File: documentation/zh-cn/02-building-your-application/04-rest-api.mdx
[Binary file]
File: documentation/zh-cn/02-building-your-application/05-web-page.mdx
title: 网页
related:
title: 下一步
links:
- admin-panel
在本节中,我们将使用简单用户界面(SUI)来构建一个显示应用程序数据的动态网页。
SUI 是一个内置的基于组件的模板引擎,使用 HTML、CSS 和 TypeScript 来创建网页。它对 AI 友好,支持服务器端渲染(SSR),并且不需要额外的构建工具。
- 🟢 在应用程序中创建和管理数据。 👉 数据模型
- 🟢 开发 RESTful API 来暴露数据。 👉 REST API
- 🟠 设计网页来显示数据。
- ⚪ 构建管理面板帮助宠物商店的管理员管理数据。 👉 Admin Panel
- ⚪ 创建后端命令用于任务调度。 👉 CLI
- ⚪ 集成 AI 用于聊天机器人、图像生成和增强用户输入。 👉 AI Integration
在继续之前,确保你已阅读了之前的文档,并且已完成了前面的步骤。
👉 数据模型
👉 构建你的应用程序
概述
SUI 是 Yao v0.10.4 中的一个新功能,它对 AI 友好并简化了网页创建和数据集成。它支持向后兼容,使开发者能够使用 HTML、CSS 和 TypeScript/JavaScript,同时通过基于组件的架构促进代码重用。
SUI 不需要额外的构建工具,并且天然支持服务器端渲染(SSR),增强了 SEO 并使其适合网站开发。
注意:SUI 是一个新功能,仍处于实验阶段。对于高级前端需求,考虑使用 React 或 Vue 等框架。将构建的文件放在 public 目录中,并通过 REST API 与 Yao 连接。
在这里访问完整的教程:👉 网站教程
如果你对我们为什么推荐 SUI 感兴趣,请阅读这篇博客文章:
步骤 1:生成网页
在这个演示中,我们将创建两个网页:一个用于列出宠物,另一个用于宠物详情。
AI 生成的网页适用于简单的网站,你可以通过编辑生成的内容进一步自定义它们。
这一步演示了如何编写提示来生成网页。
💬 生成网页的提示
这是与 AI 聊天机器人生成网页的对话示例。根据你的需求更改提示。
模型示例:
[模型示例]
相关模型:
pets, pet.categories
生成网页的指南:
- 每个网页应该由单独的纯 HTML、CSS 和 TypeScript 文件组成。使用相同的名称但不同的扩展名(例如,index.html、index.css、index.ts)。
- 避免使用框架或库。如果需要,通过 script 标签导入库。
- 渲染逻辑将由模板引擎处理,所以你不需要实现它。使用 JS 文件来处理动画。
- 对于第三方库,在 JS 文件中使用 `import '<CDN 链接>';` 包含 CDN 链接。
- HTML 内容应该排除 <head> 和 <body> 标签;这些由 SUI 引擎添加。
- 分离通用 CSS 文件以保持一致的样式,如果需要,使用 `import '@assets/[name].css';` 将它们导入到 CSS 文件中。
- 为了保持一致性,使用与模型字段相同的 CSS 类名和 ID。
- 每个文件应该用代码块包裹,顶部注释文件名。
模板引擎规则:
- 在 HTML 标签内使用 `{{ variable }}` 语法进行数据渲染。
- 使用 `s:for` 遍历数据列表,例如,`<div s:for="items" s:for-item="pet"> <span>{{ pet.name }}</span> </div>`。
- 使用 `s:if` 进行条件渲染,例如,`<span s:if="pet.name">{{ pet.name }}</span>`。
- 文件系统路由定义网页路由。例如,`index.html` 映射到 '/','about.html' 映射到 '/about'。
- 动态路由用 `[id]` 表示,例如,'/pet/1','/pet/2' 是 '/[id]'。
- 使用 `s:on-click` 进行事件绑定,例如,`<button s:on-click="handleClick" s:data-id="{{ pet.id }}">点击</button>`。
- 在 TS/JS 文件中实现事件处理程序,例如:
```typescript
import { EventData, Component, EventDetail } from "@yao/sui";
const self = this as Component;
self.handleClick = (event: Event, data: EventData, detail: EventDetail) => {
// 处理事件
// data['id'] 对应 s:data-id="{{ pet.id }}"
};
```
网页需求:
- 使用模型中的字段生成网页内容。
- 创建两个页面:'index' 用于列出宠物,'[id]' 用于宠物详情,其中 'id' 是宠物的 ID。
- 在列表页面上使用 pet.categories 模型显示宠物类别名称。
- 分离通用 CSS 文件 style.css 以保持一致的样式,在 CSS 文件中定义通用字体、颜色和间距。
- 保持一致的样式并实现动画和交互式 JS 效果。🤖 _AI 聊天机器人的回复_
AI 聊天机器人将为你生成网页,它应该像这样:
<!-- [id].html -->
<div class="pet-details">
<h1>{{ pet.pet_name }}</h1>
<p>类别:{{ pet.category_name }}</p>
<p s:if="pet.age">年龄:{{ pet.age }}</p>
<p s:if="pet.breed">品种:{{ pet.breed }}</p>
<p s:if="pet.description">{{ pet.description }}</p>
<button s:on-click="goBack">返回列表</button>
</div>/* [id].css */
@import "@assets/style.css";
.pet-details {
padding: 24px;
border: 1px solid #ccc;
border-radius: 8px;
}
button {
background-color: #007bff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}// [id].ts
import { EventData, Component, EventDetail } from "@yao/sui";
const self = this as Component;
self.goBack = () => {
window.location.href = `/`;
};步骤 2:保存网页
在继续之前,确保你已经查看了之前的文档以了解 Yao 应用程序的目录结构,并已使用快速入门指南创建了一个 Yao 应用程序。
👉 快速开始
👉 Yao 应用程序
📜 目录结构
按照快速入门指南后,你的项目根目录应该包含三个目录:data/templates/default、suis 和 public。
查看下面的 data/templates/default 目录结构:
├── data
│ └── templates
│ └── default # 模板根目录
│ ├── __assets # 资源
│ ├── __data.json # 全局动态数据
│ ├── __document.html # 文档模板
│ ├── index # 主页
│ │ └── index.html更多信息,请参阅目录结构文档:
💾 保存网页
SUI 页面使用文件系统路由进行网页路由。每个页面是一个目录,包含同名的 HTML、CSS 和 TypeScript 文件。在目录和文件名中使用 [name] 表示动态路由。
示例:
/index映射到TEMPLATE_ROOT/index/pet/[id]映射到TEMPLATE_ROOT/pet/[id]
在 data/templates/default 目录中保存生成的网页。
目录结构应该是:
├── data
│ └── templates
│ └── default # 模板根目录
│ ├── __assets
│ │ └── style.css
│ ├── __data.json
│ ├── __document.html
│ ├── index
│ │ └── index.html
│ └── pet
│ ├── [id] # 动态路由 /pet/1, /pet/2 ...
│ │ ├── [id].css
│ │ ├── [id].html
│ │ └── [id].ts
│ └── index # 宠物列表页面 /pet
│ ├── index.css
│ ├── index.html
│ └── index.ts步骤 3:构建网页
保存网页后,运行 yao sui build 命令来构建它们。这会生成 .sui 文件并将资源复制到 public 目录。
内置的 Yao HTTP 服务器将识别并提供这些网页。
📺 SUI 构建命令
在新的终端中执行以下命令:
# `web` 是在 `suis` 目录中找到的 SUI 部件 ID。每个应用程序可以有多个模板引擎实例。
# `default` 是位于 `data/templates` 目录中的模板名称。每个引擎可以有多个模板。
yao sui build web default正确的输出应该是:
-----------------------
Public Root: /public/
Template: /templates/default
Session: {}
-----------------------
Build succeeded for production in 9ms📜 URL 重写
当前 Yao 版本缺乏自动重写规则。在 app.yao 中手动添加它们。这将在未来的版本中修复。
{
"name": "Demo Application",
"short": "Demo",
"description": "Another yao application",
"version": "0.10.4",
"adminRoot": "admin",
"public": {
// 在这里添加 http 服务器重写规则
"rewrite": [
{ "^\\/assets\\/(.*)$": "/assets/$1" }, // /assets/* -> /public/assets/*
{ "^\\/pet/index$": "/pet/index.sui" }, // /pet/index -> /public/pet/index.sui
{ "^\\/pet/(.*)$": "/pet/[id].sui" }, // /pet/xxx -> /public/pet/[id].sui
{ "^\\/(.*)$": "/$1.sui" } // 其他路由,/xxx -> /xxx.sui
]
},
"optional": { "remoteCache": true }
}修改 app.yao 文件后重启服务器。 👉 应用配置
🌐 在浏览器中访问
构建网页后,你可以在浏览器中查看它们。在继续之前,确保 Yao 服务器正在运行。
在浏览器中访问以下 URL:
- http://127.0.0.1:5099/pet/index 宠物列表页面。
- http://127.0.0.1:5099/pet/1 宠物详情页面。
用你的服务器的 IP 地址和端口替换 IP 地址和端口。
步骤 4:集成数据
你已经成功使用 SUI 创建了网页。这一步演示如何将数据集成到网页中。
📜 SUI 页面部分
每个 SUI 页面最多可以包含六个部分:HTML、CSS、前端脚本、数据、后端脚本和配置。只有 HTML 是必需的。
| 部分 | 扩展名 | 必需 | 描述 |
|---|---|---|---|
| HTML | .html | 是 | 核心 HTML 内容。 |
| CSS | .css | 否 | 页面的样式。 |
| 前端脚本 | .ts | 否 | 浏览器的脚本,编译为 JS。 |
| 后端脚本 | .backend.ts | 否 | 服务器端脚本,如自定义进程。 |
| 数据 | .json | 否 | 数据源,在 HTML 中使用 {{ key }} 渲染。 |
| 配置 | .config | 否 | 页面设置,如标题、缓存策略。 |
💾 数据集成
我们使用后端脚本从数据库获取数据,并使用数据源文件将数据传递给 HTML 文件。
后端脚本在服务器端运行,它与 scripts 文件相同。可以在后端脚本中导入 scripts 目录中的脚本,或使用 Yao Runtime API。
后端脚本文件:
为宠物列表和宠物详情页面创建后端脚本文件。
// pet/index/index.backend.ts
import { Process } from "@yao/runtime";
function PetList() {
const pets = Process("models.pets.Get", {
select: ["id", "pet_name", "category_id"],
withs: { category: { query: { select: ["id", "category_name"] } } }, // 使用联表查询直接获取类别名称
});
return pets;
}// pet/[id]/[id].backend.ts
import { Process, SuiRequest, Exception } from "@yao/runtime";
function Pet(r: SuiRequest) {
// 从请求中获取宠物 ID
const id = r.params?.id;
if (!id) {
throw new Exception("需要宠物 ID", 400);
}
const pets = Process("models.pets.Find", id, {
select: ["id", "pet_name", "category_id"],
withs: { category: { query: { select: ["id", "category_name"] } } }, // 使用联表查询直接获取类别名称
});
return pets;
}数据源文件:
// pet/index/index.json
{
// 以 $ 为前缀的变量表示执行后端脚本函数或进程。
// 以 @ 为前缀的值表示从后端脚本获取数据;否则,将执行进程。
"$pets": "@PetList", // 执行后端脚本函数,获取数据
"$ping": "utils.app.ping", // 执行进程,获取数据
// 静态数据
"foo": { "hello": "world" }
}// pet/[id]/[id].json
{
"$pet": "@Pet" // 执行后端脚本函数,获取数据
}创建后端脚本和数据源文件后,目录结构应该是:
├── data
│ └── templates
│ └── default
│ ├── __assets
│ │ └── style.css
│ ├── __data.json
│ ├── __document.html
│ ├── index
│ │ └── index.html
│ └── pet
│ ├── [id]
│ │ ├── [id].backend.ts # 宠物详情页面的新后端脚本文件
│ │ ├── [id].css
│ │ ├── [id].html
│ │ ├── [id].json # 宠物详情页面的新数据源文件
│ │ └── [id].ts
│ └── index
│ ├── index.backend.ts # 宠物列表页面的新后端脚本文件
│ ├── index.css
│ ├── index.html
│ ├── index.json # 宠物列表页面的新数据源文件
│ └── index.ts
├── models
│ ├── goods.mod.yao
│ ├── pet
│ │ └── categories.mod.yao
│ ├── pets.mod.yao # 修改模型 DSL,添加关系
│ └── transactions.mod.yao📝 注意:
在后端脚本中,使用带有 withs 选项的 Process 函数来联表类别表并直接获取类别名称。
我们应该修改 Model DSL 以支持联表查询,这理想情况下应该在创建 DSL 文件时完成。它放在这里是为了演示如何更新模型 DSL 和维护应用程序。
打开 models/pets.mod.yao 文件并修改 DSL 添加关系;
// models/pets.mod.yao
{
"name": "Pet",
"table": { "name": "pets", "comment": "Pets" },
"columns": [
//...
],
// 在这里添加关系
"relations": {
// category:关系名称
"category": {
"type": "hasOne", // 关系类型,hasOne 或 hasMany
"model": "pet.categories", // 关系模型部件 ID
"foreign": "category_id", // 当前模型中的外键
"key": "id" // 相关模型中的主键
}
},
"option": { "timestamps": true }
}有关数据模型的更多信息,请查看 👉 DSL 参考
步骤 5:组件(可选)
🎉 恭喜
File: documentation/zh-cn/02-building-your-application/06-admin-panel.mdx
[Empty file]
File: documentation/zh-cn/02-building-your-application/07-cli.mdx
title: 命令行界面
File: documentation/zh-cn/02-building-your-application/08-ai-integration.mdx
title: AI 集成
File: documentation/zh-cn/02-building-your-application/09-app-configuration.mdx
[Empty file]
File: documentation/zh-cn/02-building-your-application/index.mdx
title: 构建你的应用程序
以下部分将指导你使用 Yao 构建一个简单的应用程序。在开始之前,请确保 Yao 已安装在你的机器上,并查看以下部分以获取必要的背景信息。
👉 入门指南
👉 切换到 Yao
👉 安装
代码生成工具
在这个示例中,我们使用 GPT-4 来演示 AI 辅助代码创建,并向你展示如何编写提示。
但是,你可以自由使用任何其他你喜欢的模型。你也可以手动编写代码或创建自己的工具来自动生成代码。
如果你只是想学习如何构建应用程序,可以跳过这一步,直接将代码从仓库复制到你的项目中。
你也可以使用 Yao Playground 作为代码生成工具。它是一个简单的 yao 应用程序,可以为你生成代码,你可以在本地机器上运行它。
👉 演示应用仓库
Visual Studio Code 扩展
为了提升你的开发体验,我们建议安装以下 Visual Studio Code 扩展:
待添加...
阅读指南
通过按照文档中的步骤进行操作,你将很快掌握如何使用 Yao。
完成后,你将使用 Yao 构建一个简单的应用程序,包括 REST API、网页和管理面板。
你还可以将 AI 集成到管理面板中以增强你的应用程序。
阅读顺序:
👉 Yao 命令
👉 如何调试
👉 数据模型
👉 REST API
👉 创建网页
👉 管理面板
👉 命令行工具
👉 AI 集成
👉 应用程序配置
File: documentation/zh-cn/03-deploying-your-application/01-deploy-using-deploy-command.mdx
title: 使用部署命令
File: documentation/zh-cn/03-deploying-your-application/02-deploy-using-docker.mdx
title: 使用 Docker 部署
File: documentation/zh-cn/03-deploying-your-application/03-deploy-to-a-cloud-server.mdx
title: 部署到云服务器
File: documentation/zh-cn/03-deploying-your-application/04-deploy-to-an-edge-device.mdx
title: 部署到边缘设备
File: documentation/zh-cn/03-deploying-your-application/index.mdx
title: 部署你的应用程序
File: documentation/zh-cn/04-using-source-code/01-the-repositories.mdx
title: 代码仓库
File: documentation/zh-cn/04-using-source-code/02-compiling-source-code.mdx
title: 编译源代码
File: documentation/zh-cn/04-using-source-code/03-adding-your-process.mdx
title: 添加你的进程
File: documentation/zh-cn/04-using-source-code/04-adding-your-component.mdx
title: 添加你的组件
File: documentation/zh-cn/04-using-source-code/05-building-your-component-library.mdx
[Empty file]
File: documentation/zh-cn/04-using-source-code/index.mdx
title: 使用源代码
File: documentation/zh-cn/05-architecture/01-widget.mdx
title: 小部件
File: documentation/zh-cn/05-architecture/02-process.mdx
title: 进程
File: documentation/zh-cn/05-architecture/03-component.mdx
title: 组件
File: documentation/zh-cn/05-architecture/04-template-engine.mdx
title: 模板引擎
File: documentation/zh-cn/05-architecture/index.mdx
title: 架构
File: documentation/zh-cn/06-community/01-contribution-guide.mdx
title: 贡献指南
File: documentation/zh-hk/README.md
Yao 官方文档
File: references/en-us/README.md
Yao Official References
File: references/en-us/01-widget-dsl/index.mdx
[Empty file]
File: references/en-us/01-widget-dsl/01-model/01-structure.mdx
[Empty file]
File: references/en-us/01-widget-dsl/02-api/01-structure.mdx
[Empty file]
File: references/en-us/01-widget-dsl/03-table/01-structure.mdx
[Empty file]
File: references/en-us/01-widget-dsl/04-form/01-structure.mdx
[Empty file]
File: references/en-us/01-widget-dsl/05-store/01-structure.mdx
[Empty file]
File: references/en-us/02-query-dsl/01-structure.mdx
[Empty file]
File: references/en-us/02-query-dsl/02-query.mdx
[Empty file]
File: references/en-us/02-query-dsl/index.mdx
[Empty file]
File: references/en-us/03-processes/01-app.mdx
[Empty file]
File: references/en-us/03-processes/02-model.mdx
[Empty file]
File: references/en-us/03-processes/index.mdx
[Empty file]
File: references/en-us/04-components/01-structure.mdx
[Empty file]
File: references/en-us/04-components/04-actions.mdx
[Empty file]
File: references/en-us/04-components/index.mdx
[Empty file]
File: references/en-us/04-components/02-view/01-text.mdx
[Empty file]
File: references/en-us/04-components/03-chart/01-line.mdx
[Empty file]
File: references/en-us/04-components/03-edit/01-input.mdx
[Empty file]
File: references/en-us/05-jsapi/01-console.mdx
[Empty file]
File: references/en-us/05-jsapi/02-log.mdx
[Empty file]
File: references/en-us/05-jsapi/03-process.mdx
[Empty file]
File: references/en-us/05-jsapi/index.mdx
[Empty file]
File: references/en-us/06-sui/index.mdx
[Empty file]
File: references/ja-jp/README.md
Yao Official References
File: references/zh-cn/README.md
Yao Official References
File: references/zh-tw/README.md
Yao Official References
File: tutorials/en-us/README.md
Yao Official Tutorials
File: tutorials/en-us/01-website/README.md
Build website with Yao
File: tutorials/en-us/01-website/01-overview/index.mdx
title: Website Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/02-api/README.md
Build REST API with Yao
File: tutorials/en-us/02-api/01-overview/index.mdx
title: REST API Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/03-admin-panel/README.md
Build Dashboard with Yao
File: tutorials/en-us/03-admin-panel/01-overview/index.mdx
title: Admin Panel Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/04-cli/README.md
Command Line Interface Application
File: tutorials/en-us/04-cli/01-overview/index.mdx
title: Command-Line Tool Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/05-business/README.md
Enterprise Application
File: tutorials/en-us/05-business/01-overview/index.mdx
title: Business Application Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/06-edge/README.md
Edge Application
File: tutorials/en-us/06-edge/01-overview/index.mdx
title: Edge Device Application
This tutorial is under construction. Please check back later.
File: tutorials/en-us/07-ai-chatbot/README.md
AI Integration
File: tutorials/en-us/07-ai-chatbot/01-overview/index.mdx
title: AI Chatbot Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/08-ai-input/README.md
AI Integration
File: tutorials/en-us/08-ai-input/01-overview/index.mdx
title: AI-powered Input Tutorial
This tutorial is under construction. Please check back later.
psychology
File: tutorials/en-us/09-ai-agent/README.md
AI Integration
File: tutorials/en-us/09-ai-agent/01-overview/index.mdx
title: AI Agent Tutorial
This tutorial is under construction. Please check back later.
File: tutorials/en-us/10-plugin-grpc/README.md
Extension
File: tutorials/en-us/10-plugin-grpc/01-overview/index.mdx
title: GRPC Plugin Tutorial
This tutorial is under construction. Please check back later.