Closed andrei-ivanov closed 2 years ago
Ah, actually I found out how to set the version
from a different call 🤦♂️
But my comment regarding the possibility for delete
to work even without a version
still stands
The reason for this is the Optimistic Concurrency Control. Please see https://docs.commercetools.com/api/general-concepts#optimistic-concurrency-control
Cause without a version you and us never know if you want to delete the correct version as it could have been changed in the mean time. Therefor the version is required.
Btw for updates the version is required, but is meant to be sent in the Body. For DELETE the HTTP RFC says that it doesnt have a body. So the version must be sent as a query parameter.
But the same reason should be applied for updates too, without a version how can you make sure that the client doesn't unknowingly overwrites an object that was modified?
But I'm not saying that the property is not available or that it cannot be set.
I'm saying that for updates it is optional and the update
works even if it is not set, while delete
does not work without a version
.
The version is mandatory.
Please see also https://docs.commercetools.com/api/projects/types#update-type
This is the output if trying to update without a version set.
08:44:59.897 [httpclient-dispatch-2] DEBUG commercetools.types.response - io.vrap.rmf.base.client.ApiHttpResponse@3d6124b3[statusCode=400,headers=[{key=date, value=Fri, 21 Jan 2022 07:44:59 GMT}, {key=content-length, value=222}, {key=server, value=istio-envoy}, {key=x-envoy-upstream-service-time, value=4}, {key=access-control-allow-headers, value=Accept, Authorization, Content-Type, Origin, User-Agent, X-Correlation-ID}, {key=x-correlation-id, value=projects-7f44e36f-55f4-47b9-91df-0d2323747858}, {key=access-control-allow-methods, value=GET, POST, DELETE, OPTIONS}, {key=via, value=1.1 google}, {key=access-control-expose-headers, value=X-Correlation-ID}, {key=access-control-allow-origin, value=*}, {key=x-http-status-caused-by-external-upstream, value=false}, {key=access-control-max-age, value=299}, {key=content-type, value=application/json; charset=utf-8}, {key=server-timing, value=projects;dur=3}, {key=alt-svc, value=clear}],textInterpretedBody={"statusCode":400,"message":"Request body does not contain valid JSON.","errors":[{"code":"InvalidJsonInput","message":"Request body does not contain valid JSON.","detailedErrorMessage":"version: Missing required value"}]}]
java.util.concurrent.CompletionException: io.vrap.rmf.base.client.error.BadRequestException: detailMessage: Client error response [url] https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/types/c492c0f3-d297-4312-b422-0cc33f86bd2a [status code] 400 [reason phrase] Bad Request
summary: POST https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/types/c492c0f3-d297-4312-b422-0cc33f86bd2a failed with response code 400 with X-Correlation-ID `{key=x-correlation-id, value=projects-7f44e36f-55f4-47b9-91df-0d2323747858}` on 2022-01-21T07:44:59.871132Z
http response formatted body: {
"statusCode" : 400,
"message" : "Request body does not contain valid JSON.",
"errors" : [ {
"code" : "InvalidJsonInput",
"message" : "Request body does not contain valid JSON.",
"detailedErrorMessage" : "version: Missing required value"
} ]
}
http response: io.vrap.rmf.base.client.ApiHttpResponse@3d6124b3[statusCode=400,headers=[{key=date, value=Fri, 21 Jan 2022 07:44:59 GMT}, {key=content-length, value=222}, {key=server, value=istio-envoy}, {key=x-envoy-upstream-service-time, value=4}, {key=access-control-allow-headers, value=Accept, Authorization, Content-Type, Origin, User-Agent, X-Correlation-ID}, {key=x-correlation-id, value=projects-7f44e36f-55f4-47b9-91df-0d2323747858}, {key=access-control-allow-methods, value=GET, POST, DELETE, OPTIONS}, {key=via, value=1.1 google}, {key=access-control-expose-headers, value=X-Correlation-ID}, {key=access-control-allow-origin, value=*}, {key=x-http-status-caused-by-external-upstream, value=false}, {key=access-control-max-age, value=299}, {key=content-type, value=application/json; charset=utf-8}, {key=server-timing, value=projects;dur=3}, {key=alt-svc, value=clear}],textInterpretedBody={"statusCode":400,"message":"Request body does not contain valid JSON.","errors":[{"code":"InvalidJsonInput","message":"Request body does not contain valid JSON.","detailedErrorMessage":"version: Missing required value"}]}]
SDK: 7.4.0-SNAPSHOT
endpoint: POST https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/types/c492c0f3-d297-4312-b422-0cc33f86bd2a
Java: 15.0.2
cwd: /Users/jensschulze/workspace/commercetools-java-sdks/commercetools/commercetools-sdk-java-api
request: io.vrap.rmf.base.client.ApiHttpRequest@1990d74b[method=POST,uri="https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/types/c492c0f3-d297-4312-b422-0cc33f86bd2a",headers=[{key=Accept-Encoding, value=gzip}, {key=Authorization, value=**removed from output**}, {key=User-Agent, value=commercetools-sdk-java-v2/7.4.0-SNAPSHOT Java/15.0.2+7 (Mac OS X; x86_64)}],textInterpretedBody={"actions":[{"key":"random-key-12354d9d-260d-4e0e-9e30-6eb455f27080","action":"changeKey"}]}]
http request: io.vrap.rmf.base.client.ApiHttpRequest@1990d74b[method=POST,uri="https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/types/c492c0f3-d297-4312-b422-0cc33f86bd2a",headers=[{key=Accept-Encoding, value=gzip}, {key=Authorization, value=**removed from output**}, {key=User-Agent, value=commercetools-sdk-java-v2/7.4.0-SNAPSHOT Java/15.0.2+7 (Mac OS X; x86_64)}],textInterpretedBody={"actions":[{"key":"random-key-12354d9d-260d-4e0e-9e30-6eb455f27080","action":"changeKey"}]}]
http request formatted body: {
"actions" : [ {
"key" : "random-key-12354d9d-260d-4e0e-9e30-6eb455f27080",
"action" : "changeKey"
} ]
}
The only exception to this is the custom objects endpoint as it allows upsert operations and the version is optional.
https://docs.commercetools.com/api/projects/custom-objects#create-or-update-a-customobject
Hmm, I did a test earlier and it's not, at least not in all cases:
INFO : Saved brand: Brand(id=b64234b0-0a2f-4d69-a67b-4bb22fe79a2f, code=apple, name=Apple, assets=[com.commercetools.api.models.common.AssetDraftImpl@97b7e33b], approved=false)
INFO : POST https://api.europe-west1.gcp.commercetools.com/project/custom-objects 200
INFO : Saved brand: Brand(id=b64234b0-0a2f-4d69-a67b-4bb22fe79a2f, code=apple, name=Applex, assets=[com.commercetools.api.models.common.AssetDraftImpl@97b7e33b], approved=false)
INFO : GET https://api.europe-west1.gcp.commercetools.com/project/custom-objects/brands 200
INFO : id=b64234b0-0a2f-4d69-a67b-4bb22fe79a2f, container=brands, key=apple, object=Brand(id=null, code=apple, name=Applex, assets=[com.commercetools.api.models.common.AssetDraftImpl@97b7e33b], approved=false), version=2
So doing a 2nd POST
on a custom object with the same key and without a version
updates the object and increases the version
automatically and this got me confused.
Ah, and that's exactly what you said at the end of your comment...
Got it now, as I said, the custom objects exception from the rule got me confused, sorry for all the noise 🙂
If you take a look at the URL. You are POSTing to the /custom-objects
endpoint which is for all other types the Create endpoint. Other resources use for updates e.g. POST /types/{id}
Describe the bug Trying to delete a custom type I get an error that the
version
is missing, but I don't see a way to provide it.To Reproduce
projectApiRoot.types().withKey("test").delete().executeBlocking()
Expected behavior A way to be able to provide the version or delete the latest version if it's not present. Since the
update
call doesn't require aversion
, maybedelete
shouldn't either.**Stack information