How Requests Flow Through mimOE
Understanding how mimOE processes requests is essential for building efficient mims and AI agents. This guide walks through each stage of the request lifecycle, from initial HTTP request to final response.
Overview
mimOE implements a serverless execution model where mims are instantiated on-demand for each request and terminated immediately after. This approach minimizes memory footprint and ensures isolation between requests.
Stage 1: Request Reception
The lifecycle begins when the mimOE runtime receives an HTTP request.
Request Structure
All requests to mims follow standard HTTP conventions:
POST /myservice/v1/process HTTP/1.1
Host: localhost:8083
Authorization: Bearer eyJhbGc...
Content-Type: application/json
{
"input": "data"
}
Authentication Check
The runtime immediately validates the authentication token:
- Extract token from
Authorizationheader - Verify token signature and expiration
- Check permissions for the target mim
- Reject request if authentication fails
// Example: Authenticated request
const response = await fetch('http://localhost:8083/myservice/v1/process', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ input: 'data' })
});
Route Resolution
After authentication, the runtime determines:
- mim ID: Which mim to invoke
- Endpoint: Which handler function to call
- Version: Which version of the mim (if multiple deployed)
Stage 2: mim Instantiation
Once the target mim is identified, the runtime creates a new instance.
Instance Creation
For JavaScript mims:
- Create new JavaScript VM instance
- Load mim code bundle
- Inject
contextobject with runtime APIs - Call initialization (if defined)
For WASM mims:
- Load WASM module from storage
- Instantiate WebAssembly module
- Bind imported functions (storage, HTTP, etc.)
- Call WASM entry point
Context Object Injection (JavaScript)
The runtime injects a context object providing access to platform capabilities:
// The context object is globally available
// context.http - HTTP client
// context.storage - Persistent storage
// context.edge - Discovery APIs
// context.info - Node metadata
app.get('/status', (request, response) => {
response.end(JSON.stringify({ status: 'ok' }));
});
Stage 3: Request Processing
With the instance initialized, the mim processes the request.
Request Object
The request object contains all HTTP request information:
app.post('/process', (request, response) => {
// request.method - HTTP method (GET, POST, etc.)
// request.path - URL path
// request.headers - Request headers (object)
// request.query - Query parameters (object)
// request.params - URL parameters (object)
// request.body - Request body (string)
// request.authorization - Authorization header value
console.log(request.method + ' ' + request.path);
response.end(JSON.stringify({ message: 'OK' }));
});
Asynchronous Operations
mims can perform asynchronous HTTP operations using callbacks:
app.get('/data', (request, response) => {
// HTTP requests use callbacks
context.http.request({
url: 'https://api.example.com/data',
success: (result) => {
var apiData = JSON.parse(result.data);
// Storage operations are synchronous
var userData = context.storage.getItem('user:123');
response.end(JSON.stringify({
apiData: apiData,
userData: JSON.parse(userData)
}));
},
error: (err) => {
response.statusCode = 500;
response.end(err.message);
}
});
});
Stage 4: Response Generation
The mim returns a response object to the runtime.
Response Object
The response object provides methods to send HTTP responses:
response.statusCode // Set HTTP status code (default: 200)
response.writeMimeType // Set Content-Type header
response.end(body) // Send response and end request
Response Examples
// Simple response
app.get('/status', (request, response) => {
response.end(JSON.stringify({ message: 'OK' }));
});
// Response with custom status
app.post('/users', (request, response) => {
response.statusCode = 201;
response.end(JSON.stringify({ id: 'new-resource-123' }));
});
// Error response
app.post('/validate', (request, response) => {
var body = JSON.parse(request.body);
if (!body.email) {
response.statusCode = 400;
response.end(JSON.stringify({
error: 'invalid_input',
message: 'Field "email" is required'
}));
return;
}
response.end(JSON.stringify({ valid: true }));
});
Streaming Responses
Currently, mimOE does not support streaming responses (SSE, chunked encoding). All responses must be complete before returning. Streaming support is planned for a future release.
Stage 5: Instance Termination
After the response is sent to the client, the instance is immediately terminated.
Cleanup Process
Cleanup steps:
- Close open connections: Any HTTP connections opened by the instance
- Flush pending I/O: Ensure storage writes complete
- Release memory: Free heap and stack memory
- Destroy VM/module: Terminate JavaScript VM or WASM instance
- Update metrics: Record execution time, memory used, etc.
State Destruction
All in-memory state is destroyed. Variables, caches, and computed data are lost unless explicitly saved to storage.
// ❌ This state is LOST after request
var cache = {};
app.post('/data', (request, response) => {
var body = JSON.parse(request.body);
cache[body.id] = body.data; // Lost immediately after response!
response.end(JSON.stringify({ status: 'saved' }));
});
// ✅ This state persists
app.post('/data', (request, response) => {
var body = JSON.parse(request.body);
context.storage.setItem('cache:' + body.id, JSON.stringify(body.data));
response.end(JSON.stringify({ status: 'saved' }));
});
Performance Characteristics
Understanding the lifecycle helps optimize performance:
Cold Start vs. Warm Start
Cold start (first request or after idle period):
- Load mim code from storage
- Initialize VM/WASM module
- Typical overhead: 10-50ms
Warm start (subsequent requests):
- Microservice code may be cached in memory
- Still instantiates new VM/module
- Typical overhead: 5-20ms
Optimization Strategies
1. Minimize initialization work
// ❌ Slow - loads data on every request
app.get('/process', (request, response) => {
context.http.request({
url: 'https://api.example.com/config',
success: (result) => {
var config = JSON.parse(result.data);
// Process with config...
response.end('done');
},
error: (err) => {
response.statusCode = 500;
response.end(err.message);
}
});
});
// ✅ Fast - cache config in storage
app.get('/process', (request, response) => {
var config = context.storage.getItem('config');
if (config) {
// Use cached config
processWithConfig(JSON.parse(config), response);
} else {
// Fetch and cache
context.http.request({
url: 'https://api.example.com/config',
success: (result) => {
context.storage.setItem('config', result.data);
processWithConfig(JSON.parse(result.data), response);
},
error: (err) => {
response.statusCode = 500;
response.end(err.message);
}
});
}
});
2. Keep bundles small
- Smaller JavaScript bundles load faster
- Use tree-shaking and minification
- Remove unused dependencies
3. Use transactions for multiple operations
// ❌ Not atomic - could be inconsistent if interrupted
context.storage.setItem('balance:alice', String(aliceBalance - amount));
context.storage.setItem('balance:bob', String(bobBalance + amount));
// ✅ Atomic - all or nothing
context.storage.lockExecute(function() {
context.storage.setItem('balance:alice', String(aliceBalance - amount));
context.storage.setItem('balance:bob', String(bobBalance + amount));
});
Error Handling
Errors during the lifecycle are handled differently based on where they occur:
Authentication Errors
HTTP/1.1 401 Unauthorized
{
"error": "invalid_token",
"message": "The access token is invalid or expired"
}
Instantiation Errors
HTTP/1.1 500 Internal Server Error
{
"error": "instantiation_failed",
"message": "Failed to load mim"
}
Runtime Errors
app.post('/users', (request, response) => {
var body = JSON.parse(request.body);
if (!body.email) {
// Explicit error response
response.statusCode = 400;
response.end(JSON.stringify({
error: 'missing_field',
message: 'Email is required'
}));
return;
}
// Unhandled exceptions become 500 errors
throw new Error('Something went wrong'); // → 500 error
});
Timeout Errors
HTTP/1.1 504 Gateway Timeout
{
"error": "timeout",
"message": "Request processing exceeded 30 seconds"
}
Next Steps
Now that you understand the request lifecycle:
- Platform Constraints: Learn about technical limitations
- JavaScript Development: Build your first mim
- JavaScript mim Runtime API: Explore available APIs
For production mims:
- Implement proper error handling
- Use storage for any data that must persist
- Keep initialization work minimal
- Test timeout scenarios