Unified service layer facade for Eiffel web applications. Bundles authentication, email, database, CORS, rate limiting, templates, and WebSocket services.
simple_service_api provides a single SERVICE_API class that gives you access to all common web application services. It uses composition to provide access to FOUNDATION_API via api.foundation.*, maintaining clear semantic boundaries between layers.
- JWT Authentication - Create and verify JSON Web Tokens
- SMTP Email - Send emails with attachments, HTML, and TLS
- SQL Database - SQLite database with query builder and migrations
- CORS Handling - Cross-Origin Resource Sharing configuration
- Rate Limiting - Protect endpoints from abuse
- Templates - Simple template rendering with variable substitution
- WebSocket - RFC 6455 WebSocket frame encoding/decoding
- Foundation - Access via
api.foundation.*for Base64, SHA, UUID, JSON, etc.
This library bundles the following service libraries:
| Library | Purpose | Environment Variable |
|---|---|---|
| simple_jwt | JWT authentication | $SIMPLE_JWT |
| simple_smtp | Email sending | $SIMPLE_SMTP |
| simple_sql | SQLite database | $SIMPLE_SQL |
| simple_cors | CORS handling | $SIMPLE_CORS |
| simple_rate_limiter | Rate limiting | $SIMPLE_RATE_LIMITER |
| simple_template | Template rendering | $SIMPLE_TEMPLATE |
| simple_websocket | WebSocket protocol | $SIMPLE_WEBSOCKET |
| simple_foundation_api | Core utilities (composed) | $SIMPLE_FOUNDATION_API |
- Clone all required repositories
- Set environment variables for each library
- Add to your ECF:
<library name="simple_service_api"
location="$SIMPLE_SERVICE_API\simple_service_api.ecf"/>local
api: SERVICE_API
do
create api.make
-- Service-level: JWT Authentication
token := api.create_token ("secret", "user@example.com", "my-app", 3600)
if api.verify_token ("secret", token) then
print ("Token valid!%N")
end
-- Service-level: Email
smtp := api.new_smtp ("smtp.example.com", 587)
smtp.set_credentials ("user", "pass")
smtp.set_from ("sender@example.com", "Sender")
smtp.add_to ("recipient@example.com", "Recipient")
smtp.set_subject ("Hello!")
smtp.set_body ("Test email")
smtp.send
-- Service-level: Database
db := api.new_memory_database
db.execute_sql ("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
db.execute_sql ("INSERT INTO users (name) VALUES ('Alice')")
db.close
-- Service-level: CORS
cors := api.new_cors
cors.allow_origin ("https://example.com")
headers := cors.get_headers ("https://example.com", "GET")
-- Service-level: Rate Limiting
limiter := api.new_rate_limiter (100, 60) -- 100 requests per minute
if limiter.check ("client-ip").is_allowed then
-- Process request
end
-- Service-level: Templates
result := api.render_template ("Hello, {{name}}!", data)
-- Service-level: WebSocket
frame := api.new_ws_text_frame ("Hello", True)
bytes := frame.to_bytes
-- Foundation layer (via composition)
encoded := api.foundation.base64_encode ("data")
hash := api.foundation.sha256 ("password")
uuid := api.foundation.new_uuid
endnew_jwt (secret)- Create JWT handlercreate_token (secret, subject, issuer, expires)- Generate tokenverify_token (secret, token)- Verify token
new_smtp (host, port)- Create SMTP client
new_database (path)- Open/create SQLite databasenew_memory_database- Create in-memory database
new_cors- Create CORS handler with defaultsnew_cors_permissive- Create permissive CORS handler
new_rate_limiter (max_requests, window_seconds)- Create limiter
new_template- Create template enginerender_template (template, data)- Render with substitutions
new_ws_handshake- Create handshake handlernew_ws_frame_parser- Create frame parsernew_ws_text_frame (text, is_final)- Create text framenew_ws_binary_frame (data, is_final)- Create binary framenew_ws_close_frame (code, reason)- Create close framenew_ws_ping_frame,new_ws_pong_frame- Create control framesnew_ws_text_message,new_ws_binary_message- Create messages
jwt- SIMPLE_JWT instancesmtp- SIMPLE_SMTP instancecors- SIMPLE_CORS instancetemplate- SIMPLE_TEMPLATE instance
foundation- Access to FOUNDATION_API features
- Base64 -
base64_encode,base64_decode,base64_url_encode - Hashing -
sha256,sha1,md5,hmac_sha256,secure_compare - UUID -
new_uuid,new_uuid_compact,is_valid_uuid - JSON -
parse_json,new_json_object,new_json_array - CSV -
parse_csv,csv_field,csv_to_string - Markdown -
markdown_to_html - Validation -
new_validator,is_valid_email,is_valid_url - Process -
execute_command - Random -
random_integer,random_word,random_alphanumeric_string
Composition over Inheritance: When you type api., IntelliSense shows only service-level features. Use api.foundation.* for foundation features. This makes code self-documenting and easier to understand.
MIT License - Copyright (c) 2024-2025, Larry Rix
