Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
@shopware/api-client
Advanced tools
Dynamic and fully typed API Client for Shopware 6. Usable in any JavaScript and TypeScript project. You can use types generated from your custom API instance to have autocompletion and type safety.
To generate your own types use @shopware/api-gen CLI.
To take a deep dive into the topic visit the 🧑🎓 API Client Tutorial first.
Install npm package:
# ✨ Auto-detect
npx nypm install @shopware/api-client
# npm
npm install @shopware/api-client
# yarn
yarn add @shopware/api-client
# pnpm
pnpm install @shopware/api-client
# bun
bun install @shopware/api-client
Recommended practice is to create a separate module file. For example src/apiClient.ts
, and import it whenever you need to use API Client.
import { createAPIClient } from "@shopware/api-client";
// You can pick types of your current API version, the default one:
import type { operations } from "@shopware/api-client/store-api-types";
// or - RECOMMENDED - your types generated by [@shopware/api-gen](https://www.npmjs.com/package/@shopware/api-gen) CLI:
import type { operations } from "./api-types/storeApiTypes";
// you can pick cookies library of your choice
import Cookies from "js-cookie";
export const apiClient = createAPIClient<operations>({
baseURL: "https://demo-frontends.shopware.store/store-api",
accessToken: "SWSCBHFSNTVMAWNZDNFKSHLAYW",
contextToken: Cookies.get("sw-context-token"),
});
apiClient.hook("onContextChanged", (newContextToken) => {
Cookies.set("sw-context-token", newContextToken, {
expires: 365, // days
path: "/",
sameSite: "lax",
secure: shopwareEndpoint.startsWith("https://"),
});
});
import { createAdminAPIClient } from "@shopware/api-client";
The setup works the same way as creteAPIClient
function, with few differences
We provide optional credentials
parameter to createAdminAPIClient
. Which allows you to use authentication type of your choice whenever you wish to create connection to any endpoint.
Example:
import type {
operations,
} from "@shopware/api-client/admin-api-types"; // we take default admin api types from different directory than store-api - use your own types by generating schema with @shopware/api-gen CLI
import type { operations } from "./api-types/adminApiTypes"; // or use your own types generated by @shopware/api-gen CLI
const adminApiClient = createAdminAPIClient<operations>({
baseURL: `${process.env.SHOP_URL}/api`,
credentials: {
grant_type: "password",
client_id: "administration",
scopes: "write",
username: process.env.SHOP_ADMIN_USERNAME,
password: process.env.SHOP_ADMIN_PASSWORD,
},
// credentials: { // or token-based example
// grant_type: "client_credentials",
// client_id: "administration",
// client_secret: process.env.SHOP_ADMIN_TOKEN,
// },
});
await adminApiClient.invoke(...); // invoke defined endpoint
This parameter is used to store session data in cookies (or other place you want to store it), so you can keep your session persistent.
You can combine this option with credentials
property.
// example adminApiClient.ts file
import { createAdminAPIClient } from "@shopware/api-client"; // we use different function to create admin api client
import { createAdminAPIClient } from "@shopware/api-client";
import type { operations, Schemas } from "@shopware/api-client/admin-api-types"; // we take default admin api types from different directory than store-api
import Cookies from "js-cookie";
export const adminApiClient = createAdminAPIClient<operations>({
baseURL: "https://demo-frontends.shopware.store/api",
sessionData: JSON.parse(Cookies.get("sw-admin-session-data") || "{}"),
});
adminApiClient.hooks("onAuthChange", (sessionData) => {
Cookies.set("sw-admin-session-data", JSON.stringify(sessionData), {
expires: 1, // days
path: "/",
sameSite: "lax",
secure: shopwareEndpoint.startsWith("https://"),
});
});
the rest works the same as store-api client.
Take a look at example project using API Client.
import { apiClient, RequestReturnType } from "./apiClient";
// could be reactive value, you can use ApiReturnType to type it properly
let productsResponse: RequestReturnType<"readProduct">;
async function loadProducts() {
productsResponse = await apiClient.invoke("readProduct post /product", {
limit: 2,
});
}
The new API client is leveraging ofetch library, which has built in support for AbortController, timeout and other features.
Example usage of AbortController to cancell your request:
const controller = new AbortController();
const request = client.invoke("readContext get /context", {
fetchOptions: {
signal: controller.signal,
},
});
controller.abort(); // At this point client will throw an error with the information, that the request has been cancelled
Other example of using fetchOptions
for setting the timeout:
const request = client.invoke("readContext get /context", {
fetchOptions: {
timeout: 5000, // 5 seconds
},
});
All exposed options available under fetchOptions
are:
cache
duplex
keepalive
priority
redirect
retry
retryDelay
retryStatusCodes
signal
timeout
If you prefer to add another layer of abstraction you can use created previously types to define your own concept of methods.
// add for example into apiClient.ts file
const readNavigation = ({
depth,
type,
}: {
depth: number;
type: "main-navigation";
}) =>
apiClient.invoke("readNavigation post /navigation/{activeId}/{rootId}", {
headers: {
"sw-include-seo-urls": true,
},
pathParams: {
activeId: type,
rootId: type,
},
body: {
depth,
},
});
// in another file you can use it, and depth property will be set to 2 by default
import { readNavigation } from "./apiClient";
async function loadMainNavigation() {
const navigation = await readNavigation({
body: { activeId: "main-navigation", rootId: "main-navigation" },
});
}
Client is throwing ApiClientError
with detailed information returned from the API. It will display clear message in the console or you can access details
property to get raw information from the response.
import { ApiClientError } from "@shopware/api-client";
try {
// ... your request
} catch (error) {
if (error instanceof ApiClientError) {
console.error(error); // This prints message summary
console.error("Details:", error.details); // Raw response from API
} else {
console.error("==>", error); // Another type of error, not recognized by API client
}
}
Api client provides hooks to listen to events like context change, authentication change or default headers change. Example:
apiClient.hook("onDefaultHeaderChanged", (key, value) => {
// here we can detect that the default header has changed, either by the user or by the headers incoming from the API
});
calling apiClient.hook
will autocomplete the list of available hooks.
👥 Community Slack (#composable-frontends
channel)
Full changelog for stable version is available here
0643174
Thanks @patzick! - New onDefaultHeaderChanged
hook in store and admin client. This allows to track the default headers changes. Additionally manual change of the default header will also invoke this hook.#1316 15bebee
Thanks @mkucmus! - Extend Criteria type in exported admin API schema
#1323 ebb10eb
Thanks @mkucmus! - Don't send Content-Type in case of multipart/form-data.
Content-Type
header in browser context when multipart/form-data
is set.// example
const formData = new FormData();
formData.append("file", file);
const addedMediaResponse = await apiClient.invoke(
"uploadImage post /images/upload",
{
headers: {
"Content-Type": "multipart/form-data", // <-- set this one
},
accept: "application/json",
body: formData,
},
);
When invoke
method of api-client gets the headers
parameter containing multipart/form-data
Content-Type - the header will be ignored and the responsibility will be handed over to the browser - so the Content-Type=multipart/form-data
header will eventually be sent, but including a dynamic boundary params added by the browser on the fly.
FAQs
Shopware client for API connection.
The npm package @shopware/api-client receives a total of 2,870 weekly downloads. As such, @shopware/api-client popularity was classified as popular.
We found that @shopware/api-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.