- The
api/v2/admin/zone-members/{code}
endpoint has been changed toapi/v2/admin/zone-members/{id}
.
-
So far, on production environment when any non-validation related error occurred, the
FOS\RestBundle\Serializer\Normalizer\FlattenExceptionHandler
was used, even on API Platform endpoints. Now, depending on the path of the request, theFOS\RestBundle\Serializer\Normalizer\FlattenExceptionHandler
orApiPlatform\Hydra\Serializer\ErrorNormalizer
is used. If your code rely on the previous behavior, you should add the following configuration to yourconfig/packages/_sylius.yaml
file:sylius_api: legacy_error_handling: true
Example response before bugfix:
{ "code": 500, "message": "Internal Server Error" }
Example response after bugfix:
{ "@context": "/api/v2/contexts/Error", "@type": "hydra:Error", "hydra:title": "An error occurred", "hydra:description": "Internal Server Error" }
The status code is passed along the response as an HTTP status code, and the
message
value is returned in ahydra:description
field.
-
The
Sylius\Bundle\ApiBundle\DataProvider\CartShippingMethodsSubresourceDataProvider
has been removed and replaced bySylius\Bundle\ApiBundle\DataProvider\ShippingMethodsCollectionDataProvider
. -
The
Sylius\Bundle\ApiBundle\Provider\CustomerProviderInterface
has been refactored and moved toCoreBundle
useSylius\Bundle\CoreBundle\Resolver\CustomerResolverInterface
instead. -
The
Sylius\Bundle\ApiBundle\Serializer\ShippingMethodNormalizer
logic and constructor has been changed due to refactor above.public function __construct( private OrderRepositoryInterface $orderRepository, private ShipmentRepositoryInterface $shipmentRepository, private ServiceRegistryInterface $shippingCalculators, + private RequestStack $requestStack, + private ChannelContextInterface $channelContext ) { ... }
-
The
GET
api/v2/shop/orders/{token}/shipments/{id}/methods
andapi/v2/shop/shipments/{id}/methods
endpoints have been removed and changed into collection request with 2 parametersapi/v2/shop/shipping-methods?shipmentId={id}&tokenValue={token}
. Now when we do not provide parameters in response it returns all availableshippingMethods
in channel. Wrong parameters otherwise cause empty array[]
in response and correct parameters returnshippingMethods
available for yourshipment
.
Here is how the response looks like:{ "@context": "/api/v2/contexts/ShippingMethod", "@id": "/api/v2/shop/shipping-methods", "@type": "hydra:Collection", "hydra:member": [ { "@id": "/api/v2/shop/shipping-methods/ups", "@type": "ShippingMethod", "id": 1, "code": "ups", "position": 0, "name": "UPS", "description": "Quasi perferendis debitis officiis ut inventore exercitationem." } ], "hydra:totalItems": 1, "hydra:search": { "@type": "hydra:IriTemplate", "hydra:template": "/api/v2/shop/shipping-methods{?shipmentId,tokenValue}", "hydra:variableRepresentation": "BasicRepresentation", "hydra:mapping": [ { "@type": "IriTemplateMapping", "variable": "shipmentId", "property": null, "required": false }, { "@type": "IriTemplateMapping", "variable": "tokenValue", "property": null, "required": false } ] } }
-
Service
src/Sylius/Bundle/ApiBundle/DataProvider/CartPaymentMethodsSubresourceDataProvider.php
has been removed and logic was replaced bysrc/Sylius/Bundle/ApiBundle/DataProvider/PaymentMethodsCollectionDataProvider.php
-
Endpoints
/shop/orders/{tokenValue}/payments/{payments}/methods
,/shop/payments/{id}/methods
has been removed and replaced by/shop/payment-methods
with filterpaymentId
andtokenValue
/shop/payment-methods
returns all enable payment methods if filters are not set, payment methods related to payment if filters are filled or empty response if filters ale filled with invalid data. -
Service
Sylius\Bundle\ApiBundle\DataProvider/CartPaymentMethodsSubresourceDataProvider
has been removed and logic was replaced bySylius\Bundle\ApiBundle\DataProvider\PaymentMethodsCollectionDataProvider
-
The
GET
api/v2/shop/orders/{tokenValue}/payments/{payments}/methods
andapi/v2/shop/payments/{id}/methods
endpoints have been removed and changed into collection request with 2 parametersapi/v2/shop/payment-methods?paymentId={id}&tokenValue={token}
. Now when we do not provide parameters in response it returns all availablepaymentMethods
in channel. Wrong parameters otherwise cause empty array[]
in response and correct parameters returnpaymentMethods
available for yourpayment
. -
All arguments of
src/Sylius/Bundle/ApiBundle/CommandHandler/Account/ResetPasswordHandler
have been removed and substituted withSylius\Bundle\CoreBundle\Security\UserPasswordResetter
. -
The file
src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ResetPassword.xml
has been renamed tosrc/Sylius/Bundle/ApiBundle/Resources/config/api_resources/AccountResetPassword.xml
and its short name has been changed fromResetPasswordRequest
toAccountResetPasswordRequest
. -
Constructor of
Sylius\Bundle\ApiBundle\CommandHandler\Account\RequestResetPasswordTokenHandler
has been extended withSylius\Calendar\Provider\DateTimeProviderInterface
argument:public function __construct( private UserRepositoryInterface $userRepository, private MessageBusInterface $commandBus, - private GeneratorInterface $generator + private GeneratorInterface $generator, + private DateTimeProviderInterface $calendar ) { }
-
Constructor of
\Sylius\Bundle\ApiBundle\CommandHandler\Account\VerifyCustomerAccountHandler
has been extended withSylius\Calendar\Provider\DateTimeProviderInterface
argument:- public function __construct(private RepositoryInterface $shopUserRepository) - { + public function __construct( + private RepositoryInterface $shopUserRepository, + private DateTimeProviderInterface $calendar + ) { }
-
The 2nd parameter
localeCode
has been removed fromsrc/Sylius/Bundle/ApiBundle/Command/Cart/PickupCart.php
and now is set automatically bysrc/Sylius/Bundle/ApiBundle/DataTransformer/LocaleCodeAwareInputCommandDataTransformer.php
. -
The responses of endpoints
/api/v2/admin/products
and/api/v2/admin/products/{code}
have been changed in such a way that the fielddefaultVariant
has been removed. -
The configuration of
config/packages/security.yaml
has to be updated:security: access_control: + - { path: "%sylius.security.new_api_admin_route%/reset-password-requests", role: IS_AUTHENTICATED_ANONYMOUSLY }
-
The second argument
$billingAddress
ofSylius\Bundle\ApiBundle\Modifier\OrderAddressModifierInterface::modify
has become nullable. -
The
Sylius\Bundle\ApiBundle\Assigner\OrderPromoCodeAssignerInterface
has been renamed toSylius\Bundle\ApiBundle\Assigner\OrderPromotionCodeAssignerInterface
.
In the 1.12
version we changed the way of defining API clients in our behat contexts.
We extended the Sylius/Behat/Client/ApiClientInterface
methods with extra parameter $resource
.
- public function index(): Response
+ public function index(string $resource): Response
- public function subResourceIndex(string $subResource, string $id): Response;
+ public function subResourceIndex(string $resource, string $subResource, string $id): Response;
- public function show(string $id): Response;
+ public function show(string $resource, string $id): Response;
- public function delete(string $id): Response;
+ public function delete(string $resource, string $id): Response;
- public function applyTransition(string $id, string $transition, array $content = []): Response;
+ public function applyTransition(string $resource, string $id, string $transition, array $content = []): Response;
- public function customItemAction(string $id, string $type, string $action): Response;
+ public function customItemAction(string $resource, string $id, string $type, string $action): Response;
- public function buildCreateRequest(): void;
+ public function buildCreateRequest(string $resource): void;
- public function buildUpdateRequest(string $id): void;
+ public function buildUpdateRequest(string $resource, string $id): void;
- public function buildUploadRequest(): void;
+ public function buildUploadRequest(string $resource): void;
With this change, we reduced the number of clients from one per resource to only two, one for the shop
section and one for the admin
. To make a call for a specific resource you must pass it inside the methods shown above.
You can see the actual difference in the example below:
- $this->avatarImagesClient->buildUploadRequest();
+ $this->client->buildUploadRequest(Resources::AVATAR_IMAGES);
The Sylius\Behat\Context\Api\Resources
class contains constants for all the defined resources.
We also removed the Sylius\Behat\Client\ApiPlatformIriClient
alongside with Sylius\Behat\Client\ApiIriClientInterface
as it's no more used.
The constructors of the behat contexts have changed in relation to the above improvements.
Here is the example change of the constructor of Sylius\Behat\Context\Api\Admin\ManagingOrdersContext
public function __construct(
private ApiClientInterface $client,
- private ApiClientInterface $shipmentsClient,
- private ApiClientInterface $paymentsClient,
...
)
The list of changed contexts:
- Sylius\Behat\Context\Api\Admin\ManagingAdministratorsContext
- Sylius\Behat\Context\Api\Admin\ManagingCatalogPromotionsContext
- Sylius\Behat\Context\Api\Admin\ManagingChannelsContext
- Sylius\Behat\Context\Api\Admin\ManagingCountriesContext
- Sylius\Behat\Context\Api\Admin\ManagingCurrenciesContext
- Sylius\Behat\Context\Api\Admin\ManagingCustomerGroupsContext
- Sylius\Behat\Context\Api\Admin\ManagingExchangeRatesContext
- Sylius\Behat\Context\Api\Admin\ManagingLocalesContext
- Sylius\Behat\Context\Api\Admin\ManagingOrdersContext
- Sylius\Behat\Context\Api\Admin\ManagingPaymentsContext
- Sylius\Behat\Context\Api\Admin\ManagingProductAssociationTypesContext
- Sylius\Behat\Context\Api\Admin\ManagingProductOptionsContext
- Sylius\Behat\Context\Api\Admin\ManagingProductReviewsContext
- Sylius\Behat\Context\Api\Admin\ManagingProductVariantsContext
- Sylius\Behat\Context\Api\Admin\ManagingProductsContext
- Sylius\Behat\Context\Api\Admin\ManagingPromotionsContext
- Sylius\Behat\Context\Api\Admin\ManagingShipmentsContext
- Sylius\Behat\Context\Api\Admin\ManagingShippingCategoriesContext
- Sylius\Behat\Context\Api\Admin\ManagingShippingMethodsContext
- Sylius\Behat\Context\Api\Admin\ManagingTaxCategoriesContext
- Sylius\Behat\Context\Api\Admin\ManagingZonesContext
- Sylius\Behat\Context\Api\Shop\AddressContext
- Sylius\Behat\Context\Api\Shop\CartContext
- Sylius\Behat\Context\Api\Shop\ChannelContext
- Sylius\Behat\Context\Api\Shop\CheckoutContext
- Sylius\Behat\Context\Api\Shop\CurrencyContext
- Sylius\Behat\Context\Api\Shop\CustomerContext
- Sylius\Behat\Context\Api\Shop\HomepageContext
- Sylius\Behat\Context\Api\Shop\LocaleContext
- Sylius\Behat\Context\Api\Shop\LoginContext
- Sylius\Behat\Context\Api\Shop\OrderContext
- Sylius\Behat\Context\Api\Shop\OrderItemContext
- Sylius\Behat\Context\Api\Shop\PaymentContext
- Sylius\Behat\Context\Api\Shop\ProductContext
- Sylius\Behat\Context\Api\Shop\ProductReviewContext
- Sylius\Behat\Context\Api\Shop\ProductVariantContext
- Sylius\Behat\Context\Api\Shop\PromotionContext
- Sylius\Behat\Context\Api\Shop\RegistrationContext
- Sylius\Behat\Context\Api\Shop\ShipmentContext
We removed some methods from Sylius\Behat\Client\RequestInterface
.
All of them have their corresponding implementation in Sylius\Behat\Client\RequestFactory
.
- public static function index(
- ?string $section,
- string $resource,
- string $authorizationHeader,
- ?string $token = null
- ): self;
- public static function subResourceIndex(?string $section, string $resource, string $id, string $subResource): self;
- public static function show(
- ?string $section,
- string $resource,
- string $id,
- string $authorizationHeader,
- ?string $token = null
- ): self;
- public static function create(
- ?string $section,
- string $resource,
- string $authorizationHeader,
- ?string $token = null
- ): self;
- public static function update(
- ?string $section,
- string $resource,
- string $id,
- string $authorizationHeader,
- ?string $token = null
- ): self;
- public static function delete(
- ?string $section,
- string $resource,
- string $id,
- string $authorizationHeader,
- ?string $token = null
- ): self;
- public static function transition(?string $section, string $resource, string $id, string $transition): self;
- public static function customItemAction(?string $section, string $resource, string $id, string $type, string $action): self;
- public static function upload(
- ?string $section,
- string $resource,
- string $authorizationHeader,
- ?string $token = null
- ): self;
- public static function custom(string $url, string $method, array $additionalHeaders = [], ?string $token = null): self;
Followed by this change the constructor of Sylius\Behat\Client\ApiPlatformClient
also changed:
public function __construct(
private AbstractBrowser $client,
private SharedStorageInterface $sharedStorage,
+ private RequestFactoryInterface $requestFactory,
...
) {
}
Now we are calling method by parameter $this->requestFactory
instead of calling Request
class itself.
You can see the difference of usage below:
public function index(string $resource): Response
{
- $this->request = Request::index($this->section, $resource, $this->authorizationHeader, $this->getToken());
+ $this->request = $this->requestFactory->index($this->section, $resource, $this->authorizationHeader, $this->getToken());
return $this->request($this->request);
}
The Sylius\Behat\Client\ApiClientInterface::buildUploadRequest
method has been removed, as it's replaced by methods in Sylius\Behat\Client\RequestBuilder
.
Example change of usage in Sylius\Behat\Context\Api\Admin\ManagingAdministratorsContext
:
- $this->client->buildUploadRequest(Resources::AVATAR_IMAGES);
- $this->client->addParameter('owner', $this->iriConverter->getIriFromItem($administrator));
- $this->client->addFile('file', new UploadedFile($this->minkParameters['files_path'] . $avatar, basename($avatar)));
- $response = $this->client->upload();
+ $builder = RequestBuilder::create(
+ sprintf('/api/v2/%s/%s', 'admin', Resources::AVATAR_IMAGES),
+ Request::METHOD_POST,
+ );
+ $builder->withHeader('CONTENT_TYPE', 'multipart/form-data');
+ $builder->withHeader('HTTP_ACCEPT', 'application/ld+json');
+ $builder->withHeader('HTTP_Authorization', 'Bearer ' . $this->sharedStorage->get('token'));
+ $builder->withParameter('owner', $this->iriConverter->getIriFromItem($administrator));
+ $builder->withFile('file', new UploadedFile($this->minkParameters['files_path'] . $avatar, basename($avatar)));
+ $response = $this->client->request($builder->build());
As you can see the builder contains the methods that makes the request responsive for additional headers and parameters.
We also changed the \Sylius\Behat\Client\ApiClientInterface::request
method visibility to public.
- private function request(RequestInterface $request): Response
+ public function request(RequestInterface $request): Response
Sylius\Behat\Client\ContentTypeGuide
provides solution for resolving http methods.
When we pass the proper HttpRequest
method inside of the new Sylius\Behat\Client\ContentTypeGuide::guide
method it returns appropriate json content type:
public function guide(string $method): string
{
if ($method === HttpRequest::METHOD_PATCH) {
return self::PATCH_CONTENT_TYPE;
}
if ($method === HttpRequest::METHOD_PUT) {
return self::LINKED_DATA_JSON_CONTENT_TYPE;
}
return self::JSON_CONTENT_TYPE;
}
Now to define the content type you just need to pass the appropriate HttpRequest
type inside of the guide()
method.
You can see the improvement of usage below:
- ['CONTENT_TYPE' => self::resolveHttpMethod($type)]
+ $builder->withHeader('CONTENT_TYPE', $this->contentTypeGuide->guide($type));
The constructors of the behat contexts have changed in relation to the above improvements.
public function __construct(
+ private RequestFactoryInterface $requestFactory,
...
) {
List of changed contexts:
- Sylius\Behat\Context\Api\Admin\ManagingAdministratorsContext
- Sylius\Behat\Context\Api\Shop\CartContext
- Sylius\Behat\Context\Api\Shop\CheckoutContext
- Sylius\Behat\Context\Api\Shop\CustomerContext
- Sylius\Behat\Context\Api\Shop\LoginContext
- Sylius\Behat\Context\Api\Shop\OrderContext
- Sylius\Behat\Context\Api\Shop\ProductContext