2: Integrate BigCommerce data
2: Integrate BigCommerce data
The previous exercise built the gift certificates UI entirely in “MOCK” mode, so nothing you saw came from a real BigCommerce store. In this exercise, you’ll switch to “STATIC” mode: using data from a real store using a real API token. This will allow you to focus on the details of API requests to BigCommerce while still not yet worrying about single-click install flow, session handling, or storage.
Create a store-level API account
Create a store-level API account in your store’s control panel at Settings > API > Store-level API accounts, with the following scopes:
- Modify: Marketing (gift certificates), Customers
- Read-only: Channel Settings, Channel Listings, Information & Settings
For background on API accounts, OAuth scopes, and how BigCommerce authenticates API requests, see API accounts.
In .env.local in your project (and .env.example), switch DATA_MODE and add your store hash and access token, as well as a config value
to enable API request logging:
Restart the dev server after changing .env.local.
Introduce the real REST client
The project boilerplate already contains a basic BcRestApiClient interface and a getRestApiClient controller function (currently only equipped to
return a mock client). In this first step, you’ll create a basic API client used whenever the data mode is not “MOCK”.
Build the REST client
This is the most verbose step of this exercise. Build a REST API client that implements BcRestApiClient and supports GET, POST, PUT, and DELETE requests.
Replace the contents of src/lib/bc-api-client/rest-client/rest-client.ts.
This is the basic shell of the client and several useful utility functions. Note that the BigCommerce base REST URL is stored in the constant
API_BASE_URL. Also note the import of several pre-existing types from the project boilerplate, defining the shape of data like credentials (a store hash and token)
and basic request/response shapes. These are fairly generic, not representing the shape of any particular API endpoint, and you can feel free
to examine the interfaces.
The client itself expects credentials to be passed into the constructor when first instantiated.
Now add a get method to the client:
This method wraps a simple fetch, executed with the appropriate endpoint URL, querystring params, and authentication header.
Note that get defines a TypeScript generic (TResponse), allowing the caller to specify an expected response shape specific
to the endpoint being called.
Finally, add the mutating methods. Since POST, PUT, and DELETE all use the same pattern (a fetch with the appropriate HTTP method and optionally a body)
the public methods wrap the same private mutate method.
A few details worth calling out:
- Query strings can carry PII. This app’s endpoints support searching gift certificates by recipient email, so the request logger only logs a path’s parameter names, never their values.
- No retry or timeout logic yet. You’ll have the opportunity after the tutorial to examine an implementation of these features.
Resolve the store hash and API token
Before you can implement the central controller, it’s necessary to flesh out the logic the application uses to resolve the store hash and token for API requests. Remember, the app supports multiple data modes, and you’re starting with “STATIC” for your first requests.
- In “MOCK” mode, there is no store hash and no token to resolve, regardless of any store hash in the URL path.
- In “STATIC” mode, both store hash and token are resolved from static environment variables, also regardless of any store hash in the URL path.
- In “MULTITENANT” mode (full single-click app context), the store hash is detected from a URL segment, and the token matching that store will be looked up from storage.
Update src/lib/bc-api-client/resolve-store-credentials.ts to flesh out both functions.
The storeHash value passed into both functions will come from the corresponding URL segment in the app’s routes. You’re not currently using
any such URLs as you’re testing your app, but store-scoped URL paths will be central to the workflow once you’re in a single-click
context in the BigCommerce control panel.
Select the client based on data mode
It’s time to update getRestApiClient to support the real API client.
Update src/lib/bc-api-client/get-rest-api-client.ts.
Note the controller function’s support for a “mock” REST API client. This will ensure that “MOCK” mode continues to function as expected after you’ve updated the data access layer to make use of the API client surface.
Fetch gift certificates through the real REST client
Your API client implementation is now prepared to take care of authentication, response handling, and data mode switching. Now it’s time to use this layer for the specific API requests that drive the gift certificate manager.
Remember that the UI you built in the previous exercises makes use of existing data access layer functions like fetchGiftCertificates. You weren’t
previously concerned with the details of these functions. In the project boilerplate, they directly use the handlers that return mock data. It’s
time to update this layer to make real API requests.
Fetch the certificates list from the real client
Update src/lib/gift-certs-manager/gift-certificates/gift-certificates-api.ts to remove the mock list handler import:
Update the same file to implement fetchGiftCertificatesPage.
You should also delete the import statement for handleGiftCertificatesListRequest from the mock/gift-certificates-list-handler file.
fetchGiftCertificatesPage handles the heavy lifting of fetching a single page of gift certificate results from the appropriate API endpoint.
Examine the details of the GiftCertificatesQuery type to see the expected shape of the querystring parameters that specify the page size and page number.
Examine the details of the GiftCertificateWireRecord type to see the expected shape of each item in the response.
The function fetchGiftCertificates in the same file remains untouched. This function uses fetchGiftCertificatesPage to fetch the results set
but also performs a “look-ahead” request for the next page of results. v2 endpoints like those used for gift certificates don’t return meta information
about total results, so the look-ahead provides information the UI needs to determine whether to allow a “next page” navigation.
Browse to the gift certificates list page. You should now see real gift certificates from your store, paginated using the real endpoint’s page/limit/sort/direction params.
Fetch and update a single gift certificate through the real REST client
You’ve implemented a real API request for the data fetch on the list page. All that’s left is the requests on the detail page.
Fetch and update a single certificate
Update src/lib/gift-certs-manager/gift-certificates/gift-certificates-api.ts to remove the remaining mock-related imports:
Update the same file and implement the fetchGiftCertificate function.
Now update the same file to implement the updateGiftCertificate function.
You should also delete the imports for getDataMode and handleGiftCertificateDetailRequest. Switching based on data mode is handled by the client,
and the handler is specific to mock data.
updateGiftCertificate is shared by every gift certificate mutation — status updates and balance refills alike. Callers pass only the field or fields they’re actually changing, and this function fills in whatever else BigCommerce’s PUT endpoint requires from the certificate’s current state. There’s deliberately no mock-mode support for this path: mock mode exists for building and demoing UI, not for round-tripping writes against in-memory data.
Browse to a gift certificate’s detail page and try a status update or balance refill action. You should see the change persist against your real store, since these actions now call updateGiftCertificate against the real REST client.
Note that the example code also updates the mock-related functions in their source files to avoid exporting them.
Full step code
Your app is now fully functional as a standalone experience, reading and updating your real BigCommerce store data. Critically, it’s currently using a hard-coded API token, with no user authentication whatsoever. In the next exercise, you’ll implement the necessary workflow to embed the app in the BigCommerce control panel and support the platform-initiated authentication.