The REST-RPC architecture synergizes REST API principles with RPC methodologies, enhancing service operations while ensuring discoverability. Ideal for microservices and backend for frontend systems, it organizes APIs around services, offering multiple actions within a standardized interface for effective service management.
The REST-RPC architecture represents a unique hybrid approach that combines the principles of REST APIs with the explicit operation naming typically found in Remote Procedure Calls (RPC). This architecture centralizes API service operations while ensuring REST-like discoverability, making it particularly beneficial for microservices and Backend for Frontend (BFF) systems.
Designed to cater to the needs of microservices that aim to maintain a REST-like environment, the REST-RPC architecture excels in creating a service-oriented design that is ideal for both event-driven systems and complex backend operations. The API organization is centered around services—collections of related actions—rather than traditional resource-oriented models.
Service-Oriented Structure: APIs are organized around services (e.g., users, products, orders), each containing various actions (e.g., create, update, delete, login). This organization allows for a more intuitive understanding of the operations.
Standardized URL and Request Structure: The architecture employs a consistent URL pattern and request format:
{baseUrl}/{apiVersion}/services/{serviceName}
For instance: https://api.example.com/v1/services/users
Each action is executed through a standardized POST request, using a structured body format:
{
"resourceId": "optional_resource_identifier",
"action": "action_name",
"payload": {
// Action-specific data
}
}
Comprehensive Service Discovery: Built-in endpoints for service listing and detailed service information enable efficient exploration of the available API functions. For example:
GET {baseUrl}/{apiVersion}/services
This returns a list of all available services as well as individual service descriptions and available actions.
Robust Error Handling: The architecture includes a consistent error handling mechanism, ensuring that all responses adhere to a standard format. Examples of error messages are provided to help developers quickly identify issues.
The REST-RPC architecture is well-suited for:
However, certain scenarios may favor traditional REST APIs instead:
To illustrate the architecture in a practical context, consider the following service definition example:
const userService: Service = {
name: "users",
description: "User management service",
actions: [
{
name: "create",
description: "Create a new user account",
validation: {
zodSchema: z.object({
email: z.string().email(),
password: z.string().min(8),
name: z.string()
})
},
handler: async (payload, context) => {
try {
const user = await createUser(payload);
return {
status: true,
message: "User created successfully",
data: { id: user.id, email: user.email }
};
} catch (error) {
return {
status: false,
message: "Failed to create user",
data: {
code: "USER_CREATION_FAILED",
reason: error.message
}
};
}
}
}
]
};
To use this service in a client-side Call, developers can implement a straightforward fetch request:
const response = await fetch('/api/v1/services/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'create',
payload: {
email: 'user@example.com',
password: 'password123',
name: 'John Doe'
}
})
});
const result = await response.json();
if (result.status) {
console.log('User created:', result.data);
} else {
console.error('Error:', result.message, result.data);
}
In summary, the REST-RPC architecture provides a structured, scalable foundation for developing service-oriented APIs while overcoming many limitations inherent in traditional REST implementations.
No comments yet.
Sign in to be the first to comment.