Output Stream Configuration v1.13.0
Output stream configuration defines how GripMock responds to gRPC requests, supporting various response types including data, errors, headers, and streaming.
Overview
The output
section in stub configuration controls:
- Response data structure
- Error conditions and codes
- HTTP/gRPC headers
- Streaming behavior
- Response timing (delays)
- Bidirectional streaming responses
Basic Output Structure
Standard Response
output:
data:
message: "Hello World"
status: "success"
timestamp: "2024-01-01T12:00:00.000Z"
Error Response
output:
error: "Resource not found"
code: 5 # NOT_FOUND
Response with Headers
output:
headers:
"x-request-id": "req-123"
"x-cache-control": "no-cache"
data:
message: "Response with headers"
Output Fields
data
v1.13.0
Contains the response payload for successful requests.
output:
data:
userId: 12345
name: "John Doe"
email: "john@example.com"
active: true
stream
v3.3.0
Defines server-side streaming responses (array of messages).
output:
stream:
- message: "First message"
timestamp: "2024-01-01T12:00:00.000Z"
- message: "Second message"
timestamp: "2024-01-01T12:00:01.000Z"
- message: "Third message"
timestamp: "2024-01-01T12:00:02.000Z"
Note: Each stream element contains the message data directly, without a data
wrapper.
error
v2.0.0
Error message for error responses.
output:
error: "User not found"
code
v2.0.0
gRPC status code for error responses.
output:
error: "Permission denied"
code: 7 # PERMISSION_DENIED
headers
v2.1.0
HTTP/gRPC headers to include in the response.
output:
headers:
"x-request-id": "req-123"
"x-user-id": "user-456"
"x-cache-control": "no-cache"
"x-rate-limit-remaining": "100"
delay
v3.2.16
Artificial delay before sending the response.
output:
delay: 100ms
data:
message: "Delayed response"
Streaming Response Types
Server Streaming v3.3.0
For methods that return multiple responses over time:
- service: DataService
method: StreamData
input:
equals:
request_id: "req_001"
chunk_count: 5
output:
stream:
- chunk_id: "chunk_001"
sequence: 1
content: "First chunk"
timestamp: "2024-01-01T12:00:00.000Z"
- chunk_id: "chunk_002"
sequence: 2
content: "Second chunk"
timestamp: "2024-01-01T12:00:01.000Z"
- chunk_id: "chunk_003"
sequence: 3
content: "Third chunk"
timestamp: "2024-01-01T12:00:02.000Z"
Bidirectional Streaming v3.4.0
For bidirectional streaming, responses are selected based on incoming messages:
- service: ChatService
method: Chat
stream:
- equals:
user_id: "alice"
content: "Hello"
type: "MESSAGE_TYPE_TEXT"
- equals:
user_id: "alice"
content: "How are you?"
type: "MESSAGE_TYPE_TEXT"
output:
stream:
- user_id: "bob"
content: "Hello Alice!"
type: "MESSAGE_TYPE_TEXT"
timestamp: "2024-01-01T12:00:00.000Z"
- user_id: "bob"
content: "I'm doing great!"
type: "MESSAGE_TYPE_TEXT"
timestamp: "2024-01-01T12:00:01.000Z"
Bidirectional Streaming Behavior:
- Each incoming message is matched against the
inputs
patterns - Responses are selected from the
output.stream
array based on message index - If no exact match is found, the best matching stub is selected based on ranking
- Stub ranking considers exact matches, partial matches, and specificity
Client Streaming Response v3.4.0
For client streaming methods, a single response is returned after all messages:
- service: UploadService
method: UploadFile
stream:
- equals:
chunk_id: "chunk_001"
sequence: 1
total_chunks: 3
- equals:
chunk_id: "chunk_001"
sequence: 2
total_chunks: 3
- equals:
chunk_id: "chunk_001"
sequence: 3
total_chunks: 3
output:
data:
upload_id: "upload_001"
success: true
total_chunks: 3
total_size: "1500"
status: "completed"
completed_at: "2024-01-15T10:05:00Z"
Advanced Output Features
Conditional Responses
Use different outputs based on input conditions:
- service: UserService
method: GetUser
input:
equals:
user_id: "12345"
output:
data:
name: "John Doe"
email: "john@example.com"
status: "active"
- service: UserService
method: GetUser
input:
equals:
user_id: "99999"
output:
error: "User not found"
code: 5 # NOT_FOUND
Response with Metadata
Include additional metadata in responses:
output:
headers:
"x-response-time": "150ms"
"x-cache-hit": "true"
data:
result: "success"
metadata:
processed_at: "2024-01-01T12:00:00.000Z"
version: "1.0.0"
source: "mock"
Error with Details
Provide detailed error information:
output:
error: "Validation failed"
code: 3 # INVALID_ARGUMENT
data:
details:
field: "email"
reason: "Invalid email format"
suggestion: "Use valid email format"
API Version Compatibility
V1 API (Legacy)
- service: ChatService
method: SendMessage
input:
equals:
user: Alice
text: "Hello"
output:
data:
success: true
message: "1 messages processed"
V2 API (Streaming) v3.3.0
- service: ChatService
method: SendMessage
stream:
- equals:
user: Alice
text: "Hello"
output:
data:
success: true
message: "1 messages processed"
Automatic Detection:
- GripMock automatically detects V1 vs V2 format based on presence of
stream
field - V1 stubs use
input
for matching - V2 stubs use
stream
for matching - Both formats are supported simultaneously for backward compatibility
Error Ordering with Streams
When both output.stream
and output.error
/output.code
are specified for a server-streaming method:
- If
output.stream
contains messages, GripMock will send all stream messages first and then finish the RPC with the specified gRPC status error - If
output.stream
is empty, the error is returned immediately without sending messages
This mirrors real-world scenarios where a stream may emit data before failing.
Performance Considerations
Stub Ranking
GripMock uses sophisticated ranking algorithms to select the best matching stub:
- Exact Matches: Highest priority for perfect matches
- Partial Matches: Ranked based on field overlap
- Specificity: More specific stubs rank higher
- Priority: Explicit priority values override ranking
- Length Matching: For streaming, length compatibility is considered
Memory Efficiency
- Stubs are loaded once and cached in memory
- Streaming responses are generated on-demand
- Bidirectional streaming maintains minimal state per connection
Best Practices
1. Use Consistent Data Structure
# Good: Consistent structure
output:
stream:
- message: "First"
timestamp: "2024-01-01T12:00:00.000Z"
- message: "Second"
timestamp: "2024-01-01T12:00:01.000Z"
# Avoid: Inconsistent structure
output:
stream:
- message: "First"
- message: "Second"
timestamp: "2024-01-01T12:00:01.000Z"
2. Provide Meaningful Error Messages
# Good: Descriptive error
output:
error: "User with ID '12345' not found in database"
code: 5
# Avoid: Generic error
output:
error: "Not found"
code: 5
3. Use Appropriate Delays
# Good: Reasonable delay for testing
output:
delay: 100ms
data:
message: "Response"
# Avoid: Excessive delays
output:
delay: 30s
data:
message: "Response"
4. Leverage Priority for Complex Scenarios
# High priority for specific cases
- service: UserService
method: GetUser
priority: 100
input:
equals:
user_id: "12345"
exact_match: true
output:
data:
name: "John Doe"
exact: true
# Lower priority fallback
- service: UserService
method: GetUser
priority: 50
input:
equals:
user_id: "12345"
output:
data:
name: "John Doe"
fallback: true