TypeDialog/docs/web/README.md

473 lines
8.3 KiB
Markdown
Raw Permalink Normal View History

2025-12-24 03:11:32 +00:00
# TypeDialog Web Backend
HTTP server with browser-based forms powered by [Axum](https://github.com/tokio-rs/axum).
## Overview
The Web backend (`typedialog-web`) provides a full-featured HTTP server with browser-based forms. Built with Axum for high performance, supporting REST APIs, WebSockets, and modern web interfaces.
## Features
- **HTTP Server**: Fast async server with Axum
- **Browser Forms**: Responsive HTML forms with JavaScript
- **REST API**: JSON endpoints for form submission
- **Real-time Validation**: Client-side and server-side validation
- **RepeatingGroups**: Inline expandable cards with live counter
- **Mobile-Friendly**: Responsive design for all screen sizes
- **HTTPS Support**: TLS/SSL for production
- **Session Management**: Stateful forms with session persistence
## Quick Start
### Installation
```bash
cargo build --release -p typedialog-web
sudo cp target/release/typedialog-web /usr/local/bin/
# Or use just
just build::web
```
### Basic Usage
```bash
# Start server (default: http://localhost:3000)
typedialog-web --config examples/form.toml
# Custom port
typedialog-web --config form.toml --port 8080
# With HTTPS
typedialog-web --config form.toml --tls-cert cert.pem --tls-key key.pem
# From config file
typedialog-web --config config/web/production.toml
```
## Server Endpoints
### Form Endpoints
| Method | Path | Description |
| -------- | ------ | ------------- |
| `GET` | `/` | Render form HTML |
| `POST` | `/submit` | Submit form data |
| `GET` | `/api/form` | Get form definition (JSON) |
| `POST` | `/api/validate` | Validate field |
| `GET` | `/health` | Health check |
### Static Assets
| Path | Description |
| ------ | ------------- |
| `/static/css/form.css` | Form styles |
| `/static/js/form.js` | Form logic |
| `/static/js/repeating-group.js` | RepeatingGroup handler |
## Configuration
### Server Config
```toml
[web]
host = "0.0.0.0"
port = 3000
tls_enabled = false
[web.cors]
allow_origin = "*"
allow_methods = ["GET", "POST"]
allow_headers = ["Content-Type"]
[web.session]
secret_key = "change-me-in-production"
timeout_seconds = 3600
```
### TLS/HTTPS Config
```toml
[web.tls]
enabled = true
cert_path = "/path/to/cert.pem"
key_path = "/path/to/key.pem"
```
### Form Config
```toml
[form]
title = "Registration Form"
description = "User registration"
submit_text = "Register"
cancel_text = "Cancel"
[[fields]]
name = "email"
field_type = "Text"
label = "Email"
validation = "email"
required = true
```
## API Usage
### Get Form Definition
```bash
curl http://localhost:3000/api/form
```
Response:
```json
{
"form": {
"title": "Registration",
"fields": [...]
}
}
```
### Submit Form
```bash
curl -X POST http://localhost:3000/submit \
-H "Content-Type: application/json" \
-d '{"name":"John","email":"john@example.com"}'
```
Response:
```json
{
"status": "success",
"data": {
"name": "John",
"email": "john@example.com"
}
}
```
### Validate Field
```bash
curl -X POST http://localhost:3000/api/validate \
-H "Content-Type: application/json" \
-d '{"field":"email","value":"invalid"}'
```
Response:
```json
{
"valid": false,
"error": "Invalid email format"
}
```
## Frontend Features
### JavaScript API
```javascript
// Form submission
document.getElementById('form').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData);
const response = await fetch('/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await response.json();
console.log('Submitted:', result);
});
// Real-time validation
input.addEventListener('blur', async () => {
const response = await fetch('/api/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
field: input.name,
value: input.value
})
});
const result = await response.json();
if (!result.valid) {
showError(result.error);
}
});
```
### RepeatingGroups
The web backend renders RepeatingGroups as inline expandable cards:
```html
<div class="repeating-group" data-min-items="1" data-max-items="10">
<div class="items-counter">Items: 0/10</div>
<div class="items-container">
<!-- Item cards here -->
</div>
<button class="add-item-btn">Add Item</button>
</div>
```
Features:
- Click "Add Item" to create new items
- Expand/collapse cards
- Delete items
- Live counter updates
- Min/max validation
- Duplicate detection (when `unique = true`)
### Styling
Custom CSS for forms:
```css
.form-container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.field-group {
margin-bottom: 1.5rem;
}
.field-label {
font-weight: 600;
margin-bottom: 0.5rem;
}
.field-input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
}
.field-error {
color: red;
font-size: 0.875rem;
margin-top: 0.25rem;
}
.submit-btn {
background: #007bff;
color: white;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
```
## Deployment
### Development
```bash
typedialog-web --config config/web/dev.toml
```
### Production
```bash
# With systemd
sudo systemctl start typedialog-web
# Or directly
typedialog-web \
--config config/web/production.toml \
--tls-cert /etc/ssl/cert.pem \
--tls-key /etc/ssl/key.pem \
--port 443
```
### Docker
```bash
# Build image
docker build -t typedialog-web .
# Run container
docker run -p 3000:3000 \
-v $(pwd)/config:/config \
typedialog-web --config /config/web/production.toml
```
### Reverse Proxy (Nginx)
```nginx
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
```
## Use Cases
### 1. SaaS Applications
Customer onboarding forms with validation:
```bash
typedialog-web --config saas/onboarding.toml --port 443 --tls
```
### 2. Internal Tools
Admin panels and configuration interfaces:
```bash
typedialog-web --config admin/settings.toml --host 0.0.0.0
```
### 3. Public Forms
Contact forms, surveys, registrations:
```bash
typedialog-web --config public/contact.toml
```
### 4. API Integration
Headless forms with JSON API:
```bash
curl http://localhost:3000/api/form | jq .
```
## Security
### HTTPS
Always use HTTPS in production:
```toml
[web.tls]
enabled = true
cert_path = "/etc/ssl/cert.pem"
key_path = "/etc/ssl/key.pem"
```
### CORS
Configure CORS for cross-origin requests:
```toml
[web.cors]
allow_origin = "https://example.com"
allow_methods = ["GET", "POST"]
allow_headers = ["Content-Type", "Authorization"]
```
### Session Security
Use strong session secrets:
```toml
[web.session]
secret_key = "generate-random-32-byte-key"
timeout_seconds = 1800 # 30 minutes
secure_cookies = true
http_only = true
```
### Input Validation
Always validate on server-side:
```toml
[[fields]]
name = "email"
validation = "email"
required = true
[[fields]]
name = "age"
validation = "range(18..120)"
```
## Examples
See [examples/04-backends/web/](../../examples/04-backends/web/) for:
- Basic forms
- REST API integration
- RepeatingGroups
- Custom styling
- HTTPS configuration
- Multi-page forms
## Related Documentation
- [Installation](../installation.md) - Setup guide
- [Configuration](../configuration.md) - Web configuration options
- [Field Types](../field_types.md) - Available field types
- [Encryption](../encryption/) - Secure field handling
- [Examples](../../examples/04-backends/web/) - Working examples
## Troubleshooting
### "Address already in use"
Port is occupied. Use different port:
```bash
typedialog-web --config form.toml --port 8080
```
### "TLS certificate error"
Check cert paths and permissions:
```bash
ls -l /path/to/cert.pem /path/to/key.pem
```
### "CORS error"
Configure CORS in config:
```toml
[web.cors]
allow_origin = "http://localhost:3000"
```
### "Form not submitting"
Check JavaScript console for errors. Ensure `/submit` endpoint is reachable.
### "Session expired"
Increase session timeout:
```toml
[web.session]
timeout_seconds = 7200 # 2 hours
```
---
**Ready to start?** See [examples/04-backends/web/](../../examples/04-backends/web/)