require 'sinatra/base'
require 'json'
class HealthApp < Sinatra::Base
configure do
set :dump_errors, true
disable :show_exceptions
set :default_content_type, 'application/json'
end
get '/' do
content_type :json
JSON.generate(status: 'ok', service: 'health', uptime: Process.clock_gettime(Process::CLOCK_MONOTONIC).round)
end
get '/ready' do
content_type :json
ready = defined?(DB) ? DB.connected? : true
status(ready ? 200 : 503)
JSON.generate(ready: ready)
end
end
require 'sinatra/base'
require 'json'
class NotesApp < Sinatra::Base
configure do
disable :show_exceptions
set :store, {}
set :seq, 0
end
before do
content_type :json
end
helpers do
def json_body
@json_body ||= begin
raw = request.body.read
raw.empty? ? {} : JSON.parse(raw)
rescue JSON::ParserError
halt 400, JSON.generate(error: 'invalid JSON')
end
end
end
get '/notes' do
JSON.generate(settings.store.values)
end
post '/notes' do
body = json_body
halt 422, JSON.generate(error: 'text required') if body['text'].to_s.strip.empty?
id = (settings.seq += 1)
note = { 'id' => id, 'text' => body['text'], 'url' => "#{request.script_name}/notes/#{id}" }
settings.store[id] = note
status 201
JSON.generate(note)
end
get '/notes/:id' do
note = settings.store[params['id'].to_i]
halt 404, JSON.generate(error: 'not found') unless note
JSON.generate(note)
end
end
require 'rack'
require_relative 'api/health_app'
require_relative 'api/notes_app'
class RequestId
def initialize(app)
@app = app
end
def call(env)
env['HTTP_X_REQUEST_ID'] ||= format('%08x', rand(0xffffffff))
status, headers, body = @app.call(env)
headers['X-Request-Id'] = env['HTTP_X_REQUEST_ID']
[status, headers, body]
end
end
use Rack::Deflater
use RequestId
run Rack::URLMap.new(
'/health' => HealthApp.new,
'/api' => NotesApp.new
)
This snippet demonstrates the modular style of Sinatra, where each app subclasses Sinatra::Base instead of using the classic top-level DSL, and several such apps are composed into a single Rack application with Rack::URLMap. The pattern is useful when a codebase grows past a single monolithic app.rb: cohesive concerns (a health probe, a JSON API, an admin surface) each become their own self-contained Sinatra class, and mounting decisions live in config.ru rather than being tangled into route definitions.
In api/health_app.rb, HealthApp is a minimal modular app that only knows about / and /ready. Because it is mounted under a prefix later, its routes are written relative to that mount point — the app itself is prefix-agnostic. The configure block sets :dump_errors and disables :show_exceptions so the probe returns clean JSON in production rather than Sinatra's HTML error page.
In api/notes_app.rb, NotesApp is a more realistic resource. It uses a before filter to force Content-Type: application/json, a helpers block for a shared json_body reader that parses the request body once, and halt to short-circuit with proper status codes. Note that inside the app it still references /notes and /notes/:id; the mount prefix is invisible here, which keeps the app independently testable with Rack::Test against its own root.
The glue is config.ru. Rack::URLMap (constructed via the map DSL that rackup provides) matches on the longest path prefix, so /api/notes is routed to NotesApp and everything else under /health reaches HealthApp. A subtle detail is that Rack strips the matched prefix from PATH_INFO and moves it into SCRIPT_NAME before handing the request to the mounted app, which is exactly why the inner routes stay prefix-free. Shared middleware such as Rack::Deflater and a request-id logger is applied once at the top, wrapping every mounted app uniformly.
The main trade-off is that URL generation across mounts requires care, since each app only knows its own SCRIPT_NAME; using request.script_name when building absolute links keeps URLs correct regardless of where an app is mounted. This composition approach is a lightweight alternative to reaching for a heavier framework when a small service needs a few clearly separated surfaces.
Related snips
require "csv"
class PeopleCsvStream
include Enumerable
HEADERS = %w[id full_name email signed_up_at plan].freeze
Resilient CSV Export as a Streamed Response
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
Django URL namespacing and reverse lookups
import type { IncomingMessage, ServerResponse } from "http";
const MIN_BYTES = 1024;
const INCOMPRESSIBLE = /^(image|video|audio)\/|application\/(zip|gzip|x-brotli|pdf|octet-stream)/i;
Response compression (only when it helps)
import { Navigate, useLocation } from 'react-router-dom'
import { useAuth } from '@/contexts/AuthContext'
interface ProtectedRouteProps {
children: React.ReactNode
}
React Router with protected routes
import pino, { Logger } from 'pino';
import { AsyncLocalStorage } from 'node:async_hooks';
export interface Store {
requestId: string;
logger: Logger;
Request ID + structured logging (Express + pino)
import logging
import time
logger = logging.getLogger(__name__)
Django middleware for request logging and timing
Share this code
Here's the card — post it anywhere.