Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Store API: Introduce API Versioning System (#5911)
Browse files Browse the repository at this point in the history
* Fix missing dependency

* Min version exceeds required 5.6

* Move exceptions

* Move schemas under V1 namespace

* Move routes to v1

* Move RouteException

* Route versioning

* Update route and schema identifiers/init

* Rework route init to support multiple versions and multiple schema

* Tests for cart routes

* Cart coupons tests

* Batch

* extensions

* Update docs

* Update remaining tests

* woocommerce_store_api_route_version was unused

* Revert unrelated change

* Fix phpcs

* Update src/StoreApi/docs/guiding-principles.md

Co-authored-by: Thomas Roberts <[email protected]>

* Update src/StoreApi/docs/cart-items.md

Co-authored-by: Thomas Roberts <[email protected]>

* Update src/StoreApi/RoutesController.php

Co-authored-by: Thomas Roberts <[email protected]>

* Note about v1 unversioned endpoints

* Remove unused get_route_version

* 409 comment in tests

* Remove copy pasted comments

* Update all usage to v1

* Correct namespace

* More v1 namespaces

* More missing v1

* fix mocks

Co-authored-by: Thomas Roberts <[email protected]>
  • Loading branch information
2 people authored and Saad Tarhi committed Feb 26, 2022
1 parent 60dfe4b commit 5ce7558
Show file tree
Hide file tree
Showing 130 changed files with 3,519 additions and 3,530 deletions.
2 changes: 1 addition & 1 deletion assets/js/base/context/hooks/cart/use-store-cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const defaultCartData: StoreCart = {
};

/**
* This is a custom hook that is wired up to the `wc/store/cart` data
* This is a custom hook that is wired up to the `wc/store/v1/cart` data
* store.
*
* @param {Object} options An object declaring the various
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export const useCollectionData = ( {
}, [ collectionDataQueryState ] );

return useCollection( {
namespace: '/wc/store',
namespace: '/wc/store/v1',
resourceName: 'products/collection-data',
query: {
...queryState,
Expand Down
4 changes: 2 additions & 2 deletions assets/js/base/context/hooks/use-store-products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useCollectionHeader, useCollection } from './collections';

/**
* This is a custom hook that is wired up to the `wc/store/collections` data
* store for the `wc/store/products` route. Given a query object, this
* store for the `wc/store/v1/products` route. Given a query object, this
* will ensure a component is kept up to date with the products matching that
* query in the store state.
*
Expand All @@ -32,7 +32,7 @@ export const useStoreProducts = (
productsLoading: boolean;
} => {
const collectionOptions = {
namespace: '/wc/store',
namespace: '/wc/store/v1',
resourceName: 'products',
};
const { results: products, isLoading: productsLoading } = useCollection( {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const FormSubmit = () => {
};

triggerFetch( {
path: '/wc/store/cart/add-item',
path: '/wc/store/v1/cart/add-item',
method: 'POST',
data: fetchData,
cache: 'no-store',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ const CheckoutProcessor = () => {
};

triggerFetch( {
path: '/wc/store/checkout',
path: '/wc/store/v1/checkout',
method: 'POST',
data,
cache: 'no-store',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe( 'Testing Payment Method Data Context Provider', () => {
registerMockPaymentMethods( false );

fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve( JSON.stringify( previewCart ) );
}
return Promise.resolve( '' );
Expand Down Expand Up @@ -220,7 +220,7 @@ describe( 'Testing Payment Method Data Context Provider with saved cards turned
registerMockPaymentMethods( true );

fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve( JSON.stringify( previewCart ) );
}
return Promise.resolve( '' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const ActiveAttributeFilters = ( {
displayStyle,
} ) => {
const { results, isLoading } = useCollection( {
namespace: '/wc/store',
namespace: '/wc/store/v1',
resourceName: 'products/attributes/terms',
resourceValues: [ attributeObject.id ],
} );
Expand Down
2 changes: 1 addition & 1 deletion assets/js/blocks/attribute-filter/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const AttributeFilterBlock = ( {
results: attributeTerms,
isLoading: attributeTermsLoading,
} = useCollection( {
namespace: '/wc/store',
namespace: '/wc/store/v1',
resourceName: 'products/attributes/terms',
resourceValues: [ attributeObject?.id || 0 ],
shouldSelect: blockAttributes.attributeId > 0,
Expand Down
6 changes: 3 additions & 3 deletions assets/js/blocks/cart-checkout/cart/test/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe( 'Testing cart', () => {
beforeEach( () => {
act( () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve( JSON.stringify( previewCart ) );
}
return Promise.resolve( '' );
Expand Down Expand Up @@ -134,7 +134,7 @@ describe( 'Testing cart', () => {

it( 'renders empty cart if there are no items in the cart', async () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve(
JSON.stringify( defaultCartState.cartData )
);
Expand All @@ -150,7 +150,7 @@ describe( 'Testing cart', () => {

it( 'renders correct cart line subtotal when currency has 0 decimals', async () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
const cart = {
...previewCart,
// Make it so there is only one item to simplify things.
Expand Down
4 changes: 2 additions & 2 deletions assets/js/blocks/cart-checkout/mini-cart/test/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const MiniCartBlock = ( props ) => (

const mockEmptyCart = () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve(
JSON.stringify( defaultCartState.cartData )
);
Expand All @@ -43,7 +43,7 @@ const mockEmptyCart = () => {

const mockFullCart = () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve( JSON.stringify( previewCart ) );
}
return Promise.resolve( '' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const resetMockPaymentMethods = () => {
describe( 'PaymentMethods', () => {
beforeEach( () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
return Promise.resolve( JSON.stringify( previewCart ) );
}
return Promise.resolve( '' );
Expand Down
2 changes: 1 addition & 1 deletion assets/js/blocks/reviews/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const getSortArgs = ( sortValue ) => {
export const getReviews = ( args ) => {
return apiFetch( {
path:
'/wc/store/products/reviews?' +
'/wc/store/v1/products/reviews?' +
Object.entries( args )
.map( ( arg ) => arg.join( '=' ) )
.join( '&' ),
Expand Down
16 changes: 8 additions & 8 deletions assets/js/data/cart/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export function* applyExtensionCartUpdate(
): Generator< unknown, CartResponse, { response: CartResponse } > {
try {
const { response } = yield apiFetchWithHeaders( {
path: '/wc/store/cart/extensions',
path: '/wc/store/v1/cart/extensions',
method: 'POST',
data: { namespace: args.namespace, data: args.data },
cache: 'no-store',
Expand Down Expand Up @@ -255,7 +255,7 @@ export function* applyCoupon(

try {
const { response } = yield apiFetchWithHeaders( {
path: '/wc/store/cart/apply-coupon',
path: '/wc/store/v1/cart/apply-coupon',
method: 'POST',
data: {
code: couponCode,
Expand Down Expand Up @@ -296,7 +296,7 @@ export function* removeCoupon(

try {
const { response } = yield apiFetchWithHeaders( {
path: '/wc/store/cart/remove-coupon',
path: '/wc/store/v1/cart/remove-coupon',
method: 'POST',
data: {
code: couponCode,
Expand Down Expand Up @@ -340,7 +340,7 @@ export function* addItemToCart(
try {
yield triggerAddingToCartEvent();
const { response } = yield apiFetchWithHeaders( {
path: `/wc/store/cart/add-item`,
path: `/wc/store/v1/cart/add-item`,
method: 'POST',
data: {
id: productId,
Expand Down Expand Up @@ -381,7 +381,7 @@ export function* removeItemFromCart(

try {
const { response } = yield apiFetchWithHeaders( {
path: `/wc/store/cart/remove-item`,
path: `/wc/store/v1/cart/remove-item`,
data: {
key: cartItemKey,
},
Expand Down Expand Up @@ -423,7 +423,7 @@ export function* changeCartItemQuantity(
yield itemIsPendingQuantity( cartItemKey );
try {
const { response } = yield apiFetchWithHeaders( {
path: '/wc/store/cart/update-item',
path: '/wc/store/v1/cart/update-item',
method: 'POST',
data: {
key: cartItemKey,
Expand Down Expand Up @@ -459,7 +459,7 @@ export function* selectShippingRate(
try {
yield shippingRatesBeingSelected( true );
const { response } = yield apiFetchWithHeaders( {
path: `/wc/store/cart/select-shipping-rate`,
path: `/wc/store/v1/cart/select-shipping-rate`,
method: 'POST',
data: {
package_id: packageId,
Expand Down Expand Up @@ -512,7 +512,7 @@ export function* updateCustomerData(

try {
const { response } = yield apiFetchWithHeaders( {
path: '/wc/store/cart/update-customer',
path: '/wc/store/v1/cart/update-customer',
method: 'POST',
data: customerData,
cache: 'no-store',
Expand Down
2 changes: 1 addition & 1 deletion assets/js/data/cart/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { __ } from '@wordpress/i18n';

export const STORE_KEY = 'wc/store/cart';
export const STORE_KEY = 'wc/store/v1/cart';
export const CART_API_ERROR = {
code: 'cart_api_error',
message: __(
Expand Down
2 changes: 1 addition & 1 deletion assets/js/data/cart/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { STORE_KEY, CART_API_ERROR } from './constants';
*/
export function* getCartData(): Generator< unknown, void, CartResponse > {
const cartData = yield apiFetch( {
path: '/wc/store/cart',
path: '/wc/store/v1/cart',
method: 'GET',
cache: 'no-store',
} );
Expand Down
2 changes: 1 addition & 1 deletion assets/js/data/collections/constants.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const STORE_KEY = 'wc/store/collections';
export const STORE_KEY = 'wc/store/v1/collections';
export const DEFAULT_EMPTY_ARRAY = [];
2 changes: 1 addition & 1 deletion assets/js/data/query-state/constants.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const STORE_KEY = 'wc/store/query-state';
export const STORE_KEY = 'wc/store/v1/query-state';
2 changes: 1 addition & 1 deletion assets/js/data/schema/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
*
* @type {string}
*/
export const STORE_KEY = 'wc/store/schema';
export const STORE_KEY = 'wc/store/v1/schema';
2 changes: 1 addition & 1 deletion assets/js/data/shared-controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const setNonceOnFetch = ( headers: Headers ): void => {
*/
const triggerBatchFetch = ( keys: readonly APIFetchOptions[] ) => {
return triggerFetch( {
path: `/wc/store/batch`,
path: `/wc/store/v1/batch`,
method: 'POST',
data: {
requests: keys.map( ( request: APIFetchOptions ) => {
Expand Down
23 changes: 13 additions & 10 deletions assets/js/editor-components/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ const getProductsRequests = ( {
order: 'asc',
};
const requests = [
addQueryArgs( '/wc/store/products', { ...defaultArgs, ...queryArgs } ),
addQueryArgs( '/wc/store/v1/products', {
...defaultArgs,
...queryArgs,
} ),
];

// If we have a large catalog, we might not get all selected products in the first page.
if ( isLargeCatalog && selected.length ) {
requests.push(
addQueryArgs( '/wc/store/products', {
addQueryArgs( '/wc/store/v1/products', {
catalog_visibility: 'any',
include: selected,
per_page: 0,
Expand Down Expand Up @@ -85,7 +88,7 @@ export const getProducts = ( {
*/
export const getProduct = ( productId ) => {
return apiFetch( {
path: `/wc/store/products/${ productId }`,
path: `/wc/store/v1/products/${ productId }`,
} );
};

Expand All @@ -94,7 +97,7 @@ export const getProduct = ( productId ) => {
*/
export const getAttributes = () => {
return apiFetch( {
path: `wc/store/products/attributes`,
path: `wc/store/v1/products/attributes`,
} );
};

Expand All @@ -105,7 +108,7 @@ export const getAttributes = () => {
*/
export const getTerms = ( attribute ) => {
return apiFetch( {
path: `wc/store/products/attributes/${ attribute }/terms`,
path: `wc/store/v1/products/attributes/${ attribute }/terms`,
} );
};

Expand All @@ -119,7 +122,7 @@ export const getTerms = ( attribute ) => {
const getProductTagsRequests = ( { selected = [], search } ) => {
const limitTags = getSetting( 'limitTags', false );
const requests = [
addQueryArgs( `wc/store/products/tags`, {
addQueryArgs( `wc/store/v1/products/tags`, {
per_page: limitTags ? 100 : 0,
orderby: limitTags ? 'count' : 'name',
order: limitTags ? 'desc' : 'asc',
Expand All @@ -130,7 +133,7 @@ const getProductTagsRequests = ( { selected = [], search } ) => {
// If we have a large catalog, we might not get all selected products in the first page.
if ( limitTags && selected.length ) {
requests.push(
addQueryArgs( `wc/store/products/tags`, {
addQueryArgs( `wc/store/v1/products/tags`, {
include: selected,
} )
);
Expand Down Expand Up @@ -163,7 +166,7 @@ export const getProductTags = ( { selected = [], search } ) => {
*/
export const getCategories = ( queryArgs ) => {
return apiFetch( {
path: addQueryArgs( `wc/store/products/categories`, {
path: addQueryArgs( `wc/store/v1/products/categories`, {
per_page: 0,
...queryArgs,
} ),
Expand All @@ -177,7 +180,7 @@ export const getCategories = ( queryArgs ) => {
*/
export const getCategory = ( categoryId ) => {
return apiFetch( {
path: `wc/store/products/categories/${ categoryId }`,
path: `wc/store/v1/products/categories/${ categoryId }`,
} );
};

Expand All @@ -188,7 +191,7 @@ export const getCategory = ( categoryId ) => {
*/
export const getProductVariations = ( product ) => {
return apiFetch( {
path: addQueryArgs( `wc/store/products`, {
path: addQueryArgs( `wc/store/v1/products`, {
per_page: 0,
type: 'variation',
parent: product,
Expand Down
2 changes: 1 addition & 1 deletion assets/js/middleware/store-api-nonce.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const isStoreApiRequest = ( options ) => {
if ( ! url || ! options.method || options.method === 'GET' ) {
return false;
}
return /wc\/store\//.exec( url ) !== null;
return /wc\/store\/v1\//.exec( url ) !== null;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion assets/js/shared/hocs/with-product-data-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const OriginalComponentWithContext = ( props ) => {
if ( productId > 0 ) {
setIsLoading( true );
apiFetch( {
path: `/wc/store/products/${ productId }`,
path: `/wc/store/v1/products/${ productId }`,
} )
.then( ( receivedProduct ) => {
setProduct( receivedProduct );
Expand Down
Loading

0 comments on commit 5ce7558

Please sign in to comment.