FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
lightweight
lightweightglimpse2-runbook-view-glimpse-save-login-react
Remix of lightweight/glimpse2-runbook-view-glimpse-save-login
Public
Like
glimpse2-runbook-view-glimpse-save-login-react
Home
Code
8
_townie
13
backend
7
frontend
5
shared
3
.vtignore
README.md
deno.json
H
main.tsx
Branches
2
Pull requests
Remixes
History
Environment variables
6
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
backend
/
controllers
/
README.md
Code
/
backend
/
controllers
/
README.md
Search
9/5/2025
Viewing readonly version of main branch: v5
View latest version
README.md

Controllers

Business logic coordination between routes and services.

Separation of Concerns

Controllers are the business logic layer that:

  • Orchestrate multiple service calls and coordinate data flow
  • Handle environment variables and application configuration
  • Implement business rules, validation, and data transformation
  • Convert between external API formats and application data models
  • Return structured data objects (not HTTP responses)
  • Provide consistent success/error response structure

Controllers do NOT:

  • Handle HTTP request/response objects (except for specific patterns)
  • Make direct external API calls (use services instead)
  • Contain presentation logic or HTML generation (except auth flows)

Standard Response Structure

All controller functions return:

{ success: boolean, data: any | null, error: string | null, details?: string // Additional error context when available }

Controller Patterns

1. Data Controller Pattern (Recommended)

When to use: Most API endpoints, business logic that can be tested independently

Characteristics:

  • Accept simple parameters (strings, numbers, objects)
  • Return structured data objects
  • Can be called from multiple contexts (HTTP, cron, etc.)
  • Easy to unit test

Data Flow:

Route → Controller → Service(s) → External API
Route ← Controller ← Service(s) ← External API

Example: getDemoProperties(id: string)

Input Data:

id: string // Notion page UUID

Processing:

  1. Validates page ID is provided
  2. Calls getPageById(id) service
  3. Filters out button properties (business rule)
  4. Returns sanitized page data

Output Data:

{ success: true, data: { id: string, properties: { // All properties except type: "button" [key: string]: NotionPropertyValue }, parent: NotionParent, // ... other page fields }, error: null }

Example: getDemoFull(id: string)

Input Data:

id: string // Notion page UUID

Processing:

  1. Validates page ID is provided
  2. Calls getPageWithBlocks(id) service (orchestrates page + blocks)
  3. Filters out button properties (business rule)
  4. Returns complete page with content

Output Data:

{ success: true, data: { // Page properties (filtered) id: string, properties: { [key: string]: NotionPropertyValue }, // Block content (hierarchical) blocks: NotionBlock[], // ... other page fields }, error: null }

2. HTTP Handler Pattern (Use Sparingly)

When to use: Authentication flows, webhooks, redirects, HTML responses

Characteristics:

  • Accept Hono Context objects
  • Return HTTP Response objects directly
  • Handle HTTP-specific concerns (headers, redirects, HTML)
  • Cannot be easily unit tested or reused

Example: handleUrlWebhook(c: Context)

Input Data:

// HTTP Request Body (JSON) { data?: { id: string }, id?: string, page_id?: string } // HTTP Headers { host: string // Used to construct glimpse URL }

Processing:

  1. Extracts page ID from multiple possible webhook payload structures
  2. Extracts host header to construct glimpse URL
  3. Calls updatePageUrl(pageId, glimpseUrl) service
  4. Returns HTTP JSON response with operation status

Output Data:

// HTTP Response (JSON) { success: true, message: "Page URL updated successfully", pageId: string, url: string, // The constructed glimpse URL timestamp: string }

Example: glimpseLoginHandler(c: Context)

Input Data:

// From Auth Middleware Context userEmail: string // From Environment Variables GLANCE_DEMOS_DB_ID: string

Processing:

  1. Extracts user email from authentication context
  2. Queries user database using findUserByEmail(databaseId, email)
  3. If user not found, creates new record with createUserRecord(databaseId, email)
  4. If user found, extracts URL from various property types
  5. Validates URL format and redirects

Output Data:

  • Success: HTTP redirect to user's personalized URL
  • New User: HTTP redirect to /glimpse/thanks
  • Error: HTML error page or JSON error response

User Record Data Structure:

// Expected in Notion database { Email: { type: "email", email: string }, URL?: { type: "url", url: string } | { type: "rich_text", rich_text: [{ plain_text: string }] } }

Example: glimpseThanksHandler(c: Context)

Input Data:

// From Auth Middleware Context userEmail: string

Processing:

  1. Validates user is authenticated
  2. Generates welcome HTML page with user email
  3. Provides next steps and expectations

Output Data:

  • Success: HTML welcome page
  • Unauthenticated: HTTP redirect to /

Error Handling Patterns

Data Controller Errors

{ success: false, error: "User-friendly error message", details: "Technical error details from service", data: null }

HTTP Handler Errors

  • User-facing errors: HTML error pages with styling
  • Technical errors: JSON responses with debugging information
  • Authentication errors: Redirects to login pages

Business Logic Examples

Data Filtering

  • Remove sensitive properties (button types) from Notion responses
  • Transform external API formats to application models

User Management

  • Automatic user creation for new email addresses
  • Multi-property URL extraction with fallback logic
  • URL validation and format checking

Webhook Processing

  • Flexible payload parsing for different webhook formats
  • Dynamic URL construction based on request context
  • Comprehensive error logging and debugging

Environment Configuration

  • Database ID management from environment variables
  • API key handling (delegated to services)
  • Feature flag and configuration management
Go to top
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Product
FeaturesPricing
Developers
DocsStatusAPI ExamplesNPM Package Examples
Explore
ShowcaseTemplatesNewest ValsTrending ValsNewsletter
Company
AboutBlogCareersBrandhi@val.town
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.