Skip to content

Latest commit

 

History

History
436 lines (344 loc) · 18.3 KB

UPGRADE-API-1.12.md

File metadata and controls

436 lines (344 loc) · 18.3 KB

UPGRADE FROM v1.12.18 TO v1.12.19

  1. The api/v2/shop/adjustments/{id} endpoint has been disabled.

UPGRADE FROM v1.12.13 TO v1.12.14

  1. The api/v2/admin/zone-members/{code} endpoint has been changed to api/v2/admin/zone-members/{id}.

UPGRADE FROM v1.12.1 TO v1.12.2

  1. 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, the FOS\RestBundle\Serializer\Normalizer\FlattenExceptionHandler or ApiPlatform\Hydra\Serializer\ErrorNormalizer is used. If your code rely on the previous behavior, you should add the following configuration to your config/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 a hydra:description field.

UPGRADE FROM v1.11.X TO v1.12.0

  1. The Sylius\Bundle\ApiBundle\DataProvider\CartShippingMethodsSubresourceDataProvider has been removed and replaced by Sylius\Bundle\ApiBundle\DataProvider\ShippingMethodsCollectionDataProvider.

  2. The Sylius\Bundle\ApiBundle\Provider\CustomerProviderInterface has been refactored and moved to CoreBundle use Sylius\Bundle\CoreBundle\Resolver\CustomerResolverInterface instead.

  3. 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
        ) {
            ...
        }
  4. The GET api/v2/shop/orders/{token}/shipments/{id}/methods and api/v2/shop/shipments/{id}/methods endpoints have been removed and changed into collection request with 2 parameters api/v2/shop/shipping-methods?shipmentId={id}&tokenValue={token}. Now when we do not provide parameters in response it returns all available shippingMethods in channel. Wrong parameters otherwise cause empty array [] in response and correct parameters return shippingMethods available for your shipment.
    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
             }
           ]
         }
       }
    
  5. Service src/Sylius/Bundle/ApiBundle/DataProvider/CartPaymentMethodsSubresourceDataProvider.php has been removed and logic was replaced by src/Sylius/Bundle/ApiBundle/DataProvider/PaymentMethodsCollectionDataProvider.php

  6. Endpoints /shop/orders/{tokenValue}/payments/{payments}/methods, /shop/payments/{id}/methods has been removed and replaced by /shop/payment-methods with filter paymentId and tokenValue /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.

  7. Service Sylius\Bundle\ApiBundle\DataProvider/CartPaymentMethodsSubresourceDataProvider has been removed and logic was replaced by Sylius\Bundle\ApiBundle\DataProvider\PaymentMethodsCollectionDataProvider

  8. The GET api/v2/shop/orders/{tokenValue}/payments/{payments}/methods and api/v2/shop/payments/{id}/methods endpoints have been removed and changed into collection request with 2 parameters api/v2/shop/payment-methods?paymentId={id}&tokenValue={token}. Now when we do not provide parameters in response it returns all available paymentMethods in channel. Wrong parameters otherwise cause empty array [] in response and correct parameters return paymentMethods available for your payment.

  9. All arguments of src/Sylius/Bundle/ApiBundle/CommandHandler/Account/ResetPasswordHandler have been removed and substituted with Sylius\Bundle\CoreBundle\Security\UserPasswordResetter.

  10. The file src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ResetPassword.xml has been renamed to src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/AccountResetPassword.xml and its short name has been changed from ResetPasswordRequest to AccountResetPasswordRequest.

  11. Constructor of Sylius\Bundle\ApiBundle\CommandHandler\Account\RequestResetPasswordTokenHandler has been extended with Sylius\Calendar\Provider\DateTimeProviderInterface argument:

        public function __construct(
            private UserRepositoryInterface $userRepository,
            private MessageBusInterface $commandBus,
    -       private GeneratorInterface $generator
    +       private GeneratorInterface $generator,
    +       private DateTimeProviderInterface $calendar
        ) {
        }
  12. Constructor of \Sylius\Bundle\ApiBundle\CommandHandler\Account\VerifyCustomerAccountHandler has been extended with Sylius\Calendar\Provider\DateTimeProviderInterface argument:

    -   public function __construct(private RepositoryInterface $shopUserRepository)
    -   {
    +   public function __construct(
    +       private RepositoryInterface $shopUserRepository,
    +       private DateTimeProviderInterface $calendar
    +   ) {
        }
  13. The 2nd parameter localeCode has been removed from src/Sylius/Bundle/ApiBundle/Command/Cart/PickupCart.php and now is set automatically by src/Sylius/Bundle/ApiBundle/DataTransformer/LocaleCodeAwareInputCommandDataTransformer.php.

  14. The responses of endpoints /api/v2/admin/products and /api/v2/admin/products/{code} have been changed in such a way that the field defaultVariant has been removed.

  15. 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 }
  16. The second argument $billingAddress of Sylius\Bundle\ApiBundle\Modifier\OrderAddressModifierInterface::modify has become nullable.

  17. The Sylius\Bundle\ApiBundle\Assigner\OrderPromoCodeAssignerInterface has been renamed to Sylius\Bundle\ApiBundle\Assigner\OrderPromotionCodeAssignerInterface.

API clients refactor

New way of defining the clients

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.

Changes in contexts

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:

Admin:
  • 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
Shop:
  • 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

Creating Request refactored

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;

Changes in ApiPlatformClient

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

Defining ContentType changed

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));

Contexts Change

The constructors of the behat contexts have changed in relation to the above improvements.

   public function __construct(
   +   private RequestFactoryInterface $requestFactory,
       ...
   ) {

List of changed contexts:

Admin
  • Sylius\Behat\Context\Api\Admin\ManagingAdministratorsContext
Shop
  • 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