mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 16:47:32 +00:00
docs: extend api design with additional information and examples (#9856)
# Which Problems Are Solved There were some misunderstandings on how different points would be needed to be applied into existing API definitions. # How the Problems Are Solved - Added structure to the API design - Added points to context information in requests and responses - Added examples to responses with context information - Corrected available pagination messages - Added pagination and filter examples # Additional Changes None # Additional Context None
This commit is contained in:
114
API_DESIGN.md
114
API_DESIGN.md
@@ -73,6 +73,8 @@ For example, use `organization_id` instead of **org_id** or **resource_owner** f
|
|||||||
|
|
||||||
#### Resources and Fields
|
#### Resources and Fields
|
||||||
|
|
||||||
|
##### Context information in Requests
|
||||||
|
|
||||||
When a context is required for creating a resource, the context is added as a field to the resource.
|
When a context is required for creating a resource, the context is added as a field to the resource.
|
||||||
For example, when creating a new user, the organization's id is required. The `organization_id` is added as a field to the `CreateUserRequest`.
|
For example, when creating a new user, the organization's id is required. The `organization_id` is added as a field to the `CreateUserRequest`.
|
||||||
|
|
||||||
@@ -90,6 +92,65 @@ Only allow providing a context where it is required. The context MUST not be pro
|
|||||||
For example, when retrieving or updating a user, the `organization_id` is not required, since the user can be determined by the user's id.
|
For example, when retrieving or updating a user, the `organization_id` is not required, since the user can be determined by the user's id.
|
||||||
However, it is possible to provide the `organization_id` as a filter to retrieve a list of users of a specific organization.
|
However, it is possible to provide the `organization_id` as a filter to retrieve a list of users of a specific organization.
|
||||||
|
|
||||||
|
##### Context information in Responses
|
||||||
|
|
||||||
|
When the action of creation, update or deletion of a resource was successful, the returned response has to include the time of the operation and the generated identifiers.
|
||||||
|
This is achieved through the addition of a timestamp attribute with the operation as a prefix, and the generated information as separate attributes.
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
message SetExecutionResponse {
|
||||||
|
// The timestamp of the execution set.
|
||||||
|
google.protobuf.Timestamp set_date = 1 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"2024-12-18T07:50:47.492Z\"";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTargetResponse {
|
||||||
|
// The unique identifier of the newly created target.
|
||||||
|
string id = 1 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"69629012906488334\"";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
// The timestamp of the target creation.
|
||||||
|
google.protobuf.Timestamp creation_date = 2 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"2024-12-18T07:50:47.492Z\"";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
// Key used to sign and check payload sent to the target.
|
||||||
|
string signing_key = 3 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateProjectGrantResponse {
|
||||||
|
// The timestamp of the change of the project grant.
|
||||||
|
google.protobuf.Timestamp change_date = 1 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"2025-01-23T10:34:18.051Z\"";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteProjectGrantResponse {
|
||||||
|
// The timestamp of the deletion of the project grant.
|
||||||
|
// Note that the deletion date is only guaranteed to be set if the deletion was successful during the request.
|
||||||
|
// In case the deletion occurred in a previous request, the deletion date might be empty.
|
||||||
|
google.protobuf.Timestamp deletion_date = 1 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"2025-01-23T10:34:18.051Z\"";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Global messages
|
||||||
|
|
||||||
Prevent the creation of global messages that are used in multiple resources unless they always follow the same pattern.
|
Prevent the creation of global messages that are used in multiple resources unless they always follow the same pattern.
|
||||||
Use dedicated fields as described above or create a separate message for the specific context, that is only used in the boundary of the same resource.
|
Use dedicated fields as described above or create a separate message for the specific context, that is only used in the boundary of the same resource.
|
||||||
For example, settings might be set as a default on the instance level, but might be overridden on the organization level.
|
For example, settings might be set as a default on the instance level, but might be overridden on the organization level.
|
||||||
@@ -99,6 +160,8 @@ The same applies to messages that are returned by multiple resources.
|
|||||||
For example, information about the `User` might be different when managing the user resource itself than when it's returned
|
For example, information about the `User` might be different when managing the user resource itself than when it's returned
|
||||||
as part of an authorization or a manager role, where only limited information is needed.
|
as part of an authorization or a manager role, where only limited information is needed.
|
||||||
|
|
||||||
|
##### Re-using messages
|
||||||
|
|
||||||
Prevent reusing messages for the creation and the retrieval of a resource.
|
Prevent reusing messages for the creation and the retrieval of a resource.
|
||||||
Returning messages might contain additional information that is not required or even not available for the creation of the resource.
|
Returning messages might contain additional information that is not required or even not available for the creation of the resource.
|
||||||
What might sound obvious when designing the CreateUserRequest for example, where only an `organization_id` but not the
|
What might sound obvious when designing the CreateUserRequest for example, where only an `organization_id` but not the
|
||||||
@@ -190,33 +253,54 @@ In case the permission cannot be checked by the API itself, but all requests nee
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pagination
|
## Listing resources
|
||||||
|
|
||||||
The API uses pagination for listing resources. The client can specify a limit and an offset to retrieve a subset of the resources.
|
The API uses pagination for listing resources. The client can specify a limit and an offset to retrieve a subset of the resources.
|
||||||
Additionally, the client can specify sorting options to sort the resources by a specific field.
|
Additionally, the client can specify sorting options to sort the resources by a specific field.
|
||||||
|
|
||||||
Most listing methods SHOULD provide use the `ListQuery` message to allow the client to specify the limit, offset, and sorting options.
|
### Pagination
|
||||||
```protobuf
|
|
||||||
|
|
||||||
// ListQuery is a general query object for lists to allow pagination and sorting.
|
Most listing methods SHOULD use the `PaginationRequest` message to allow the client to specify the limit, offset, and sorting options.
|
||||||
message ListQuery {
|
```protobuf
|
||||||
uint64 offset = 1;
|
message ListTargetsRequest {
|
||||||
// limit is the maximum amount of objects returned. The default is set to 100
|
// List limitations and ordering.
|
||||||
// with a maximum of 1000 in the runtime configuration.
|
optional zitadel.filter.v2beta.PaginationRequest pagination = 1;
|
||||||
// If the limit exceeds the maximum configured ZITADEL will throw an error.
|
// The field the result is sorted by. The default is the creation date. Beware that if you change this, your result pagination might be inconsistent.
|
||||||
// If no limit is present the default is taken.
|
optional TargetFieldName sorting_column = 2 [
|
||||||
uint32 limit = 2;
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
// Asc is the sorting order. If true the list is sorted ascending, if false
|
default: "\"TARGET_FIELD_NAME_CREATION_DATE\""
|
||||||
// the list is sorted descending. The default is descending.
|
}
|
||||||
bool asc = 3;
|
];
|
||||||
|
// Define the criteria to query for.
|
||||||
|
repeated TargetSearchFilter filters = 3;
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
||||||
|
example: "{\"pagination\":{\"offset\":0,\"limit\":0,\"asc\":true},\"sortingColumn\":\"TARGET_FIELD_NAME_CREATION_DATE\",\"filters\":[{\"targetNameFilter\":{\"targetName\":\"ip_allow_list\",\"method\":\"TEXT_FILTER_METHOD_EQUALS\"}},{\"inTargetIdsFilter\":{\"targetIds\":[\"69629023906488334\",\"69622366012355662\"]}}]}";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
On the corresponding responses the `ListDetails` can be used to return the total count of the resources
|
|
||||||
|
On the corresponding responses the `PaginationResponse` can be used to return the total count of the resources
|
||||||
and allow the user to handle their offset and limit accordingly.
|
and allow the user to handle their offset and limit accordingly.
|
||||||
|
|
||||||
The API MUST enforce a reasonable maximum limit for the number of resources that can be retrieved and returned in a single request.
|
The API MUST enforce a reasonable maximum limit for the number of resources that can be retrieved and returned in a single request.
|
||||||
The default limit is set to 100 and the maximum limit is set to 1000. If the client requests a limit that exceeds the maximum limit, an error is returned.
|
The default limit is set to 100 and the maximum limit is set to 1000. If the client requests a limit that exceeds the maximum limit, an error is returned.
|
||||||
|
|
||||||
|
### Filter method
|
||||||
|
|
||||||
|
All filters in List operations SHOULD provide a method if not already specified by the filters name.
|
||||||
|
```protobuf
|
||||||
|
message TargetNameFilter {
|
||||||
|
// Defines the name of the target to query for.
|
||||||
|
string target_name = 1 [
|
||||||
|
(validate.rules).string = {max_len: 200}
|
||||||
|
];
|
||||||
|
// Defines which text comparison method used for the name query.
|
||||||
|
zitadel.filter.v2beta.TextFilterMethod method = 2 [
|
||||||
|
(validate.rules).enum.defined_only = true
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
The API returns machine-readable errors in the response body. This includes a status code, an error code and possibly
|
The API returns machine-readable errors in the response body. This includes a status code, an error code and possibly
|
||||||
|
Reference in New Issue
Block a user