Apply
In REST APIs, it is customary to make a PUT request to a resource’s URI (for
example, /v1/publishers/{publisherId}/books/{bookId}) in order to create or
replace a resource.
Resource-oriented design honors this pattern through the Apply
action. These operations accept the resource and its path, which it uses to
create or replace the resource. The operation returns the final resource.
Also see the update action, with guidance on how to implement
PATCH requests.
Guidance
Section titled “Guidance”APIs may provide an apply action for a resource if it is valuable for users.
APIs should use Apply when creating resources with client-generated IDs
(e.g., ISBNs, email addresses, usernames, natural keys). See Create for
creating resources with server-generated IDs.
Apply should also be used for completely replacing an existing resource’s
entire representation. Meaning the old resource is deleted, and this new
representation is created in its place. Apply is particularly useful for
declarative clients that need to ensure the complete state of a resource
matches the provided representation.
Behavior
Section titled “Behavior”The resource must be created with the ID specified in the URI, or not at all.
The Apply action must be idempotent. Sending the same Apply request
multiple times must result in the same single resource instance without
data duplication.
If an optional field in the request is missing, it should be treated as
absent on purpose. The service should remove the field from the resource,
set it to null, or set it to a default value. You must document clearly
how your API handles missing fields.
Operation
Section titled “Operation”Apply operations are specified using the following pattern:
- The HTTP method must be PUT, and must follow the
PUTguidelines in AEP-67.- The request must be idempotent.
- Some resources take longer to be applied than is reasonable for a regular API request. In this situation, the API should use a long-running operation.
- The operation must have strong consistency.
- They must not modify read-only or server-managed fields (e.g.,
createdTime).
Apply operations must be made by sending a PUT request to the
resource’s canonical URI path:
PUT /v1/publishers/{publisherId}/books/{bookId}Requests
Section titled “Requests”- The request body must be the resource being applied.
- The request must be made to the resource’s canonical URI path with the
client-specified identifier.
- The resource must be created with this ID, or not at all.
- If read-only fields are included in the request, they should be ignored or return 400 Bad Request, depending on your API’s semantics.
- Unrecognized fields may be ignored or may cause a 400 Bad Request,
depending on the API’s semantics.
- This must be documented.
PUT /v1/publishers/123/books/client-specified-idContent-Type: application/json
{ "title": "Les Misérables", "author": "Victor Hugo", "isbn": "9780451419439"}paths: /publishers/{publisherId}/books/{bookId}: put: requestBody: content: application/json: schema: $ref: '#/components/schemas/book' required: trueResponses
Section titled “Responses”- If the resource is created, the response must return 201 Created.
- If the resource is replaced, the response must return 200 OK.
- The response may include a Location header containing the URI of the newly created resource.
The response body:
- must be the resource itself. There is no separate response schema.
- should include the complete representation of the applied resource.
- must include any fields that were provided unless they are input only.
- must include any server-generated fields (e.g.,
createdTime,updatedTime).
paths: /publishers/{publisherId}/books/{bookId}: put: responses: '200': content: application/json: schema: $ref: '#/components/schemas/book' description: Successful replace '201': headers: Location: $ref: '#/components/headers/LocationHeader' content: application/json: schema: $ref: '#/components/schemas/book' description: Successful creationErrors
Section titled “Errors”An Apply action must return appropriate error responses. For additional
guidance, see Errors and HTTP status codes.
Most common error scenarios:
- 400 Bad Request should be returned if the request body is malformed or missing required fields.
- 404 Not Found should be returned if the parent resource does not exist (e.g., creating a book under a non-existent publisher).
- See authorization checks for details on responses based on permissions.
PATCH and PUT
Section titled “PATCH and PUT”Updates must be done with a PATCH. Applies must be done with a PUT. See the PATCH and PUT section of AEP-67 for more information.
Interface Definitions
Section titled “Interface Definitions”paths: /publishers/{publisherId}/books/{bookId}: put: description: Apply method for book operationId: applyBook parameters: - in: path name: publisherId required: true schema: type: string - in: path name: bookId required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/book' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/book' description: Successful replace '201': headers: Location: $ref: '#/components/headers/LocationHeader' content: application/json: schema: $ref: '#/components/schemas/book' description: Successful creationFurther reading
Section titled “Further reading”- For ensuring idempotency in
Applyactions, see idempotency. - For naming resources involving Unicode, see unicode.
Changelog
Section titled “Changelog”- 2026-02-20: Initial creation, adapted from aep.dev AEP-137.