Skip to content

Commit c0d2078

Browse files
authored
Add extra to prepareHeaders, update documentation + tests (reduxjs#1922)
* Document missing properties on prepareHeaders signature * Add a test for forced, type, endpoint in fetchBaseQuery * Pass extra to prepareHeaders * Convert example.com urls from http->https, use nodeFetch as fetchFn in test
1 parent 0241927 commit c0d2078

18 files changed

+136
-76
lines changed

docs/rtk-query/api/fetchBaseQuery.mdx

+11-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,19 @@ It takes all standard options from fetch's [`RequestInit`](https://developer.moz
1919
- Typically a string like `https://api.your-really-great-app.com/v1/`. If you don't provide a `baseUrl`, it defaults to a relative path from where the request is being made. You should most likely _always_ specify this.
2020
- `prepareHeaders` _(optional)_
2121

22-
- Allows you to inject headers on every request. You can specify headers at the endpoint level, but you'll typically want to set common headers like `authorization` here. As a convenience mechanism, the second argument allows you to use `getState` to access your redux store in the event you store information you'll need there such as an auth token.
22+
- Allows you to inject headers on every request. You can specify headers at the endpoint level, but you'll typically want to set common headers like `authorization` here. As a convenience mechanism, the second argument allows you to use `getState` to access your redux store in the event you store information you'll need there such as an auth token. Additionally, it provides access to `extra`, `endpoint`, `type`, and `forced` to unlock more granular conditional behaviors.
2323

2424
- ```ts title="prepareHeaders signature" no-transpile
25-
;(headers: Headers, api: { getState: () => unknown }) => Headers
25+
;(
26+
headers: Headers,
27+
api: {
28+
getState: () => unknown
29+
extra: unknown
30+
endpoint: string
31+
type: 'query' | 'mutation'
32+
forced: boolean | undefined
33+
}
34+
) => Headers
2635
```
2736

2837
- `paramsSerializer` _(optional)_

docs/rtk-query/usage/automated-refetching.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
800800
import { Post, LoginResponse } from './types'
801801

802802
const api = createApi({
803-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
803+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
804804
tagTypes: ['Post', 'UNAUTHORIZED', 'UNKNOWN_ERROR'],
805805
endpoints: (build) => ({
806806
postById: build.query<Post, number>({
@@ -856,7 +856,7 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
856856
import { Post, User } from './types'
857857

858858
const api = createApi({
859-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
859+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
860860
tagTypes: ['Post', 'User'],
861861
endpoints: (build) => ({
862862
getPosts: build.query<Post[], void>({
@@ -920,7 +920,7 @@ function providesList<R extends { id: string | number }[], T extends string>(
920920
// highlight-end
921921

922922
const api = createApi({
923-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
923+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
924924
tagTypes: ['Post', 'User'],
925925
endpoints: (build) => ({
926926
getPosts: build.query({

docs/rtk-query/usage/customizing-queries.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ const axiosBaseQuery =
271271
const api = createApi({
272272
// highlight-start
273273
baseQuery: axiosBaseQuery({
274-
baseUrl: 'http://example.com',
274+
baseUrl: 'https://example.com',
275275
}),
276276
// highlight-end
277277
endpoints(build) {

packages/rtk-query-codegen-openapi/test/mocks/server.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import petstoreYAML from '../fixtures/petstore.yaml.mock';
77
// This configures a request mocking server with the given request handlers.
88

99
export const server = setupServer(
10-
rest.get('http://example.com/echo', (req, res, ctx) =>
10+
rest.get('https://example.com/echo', (req, res, ctx) =>
1111
res(ctx.json({ ...req, headers: req.headers.getAllHeaders() }))
1212
),
13-
rest.post('http://example.com/echo', (req, res, ctx) =>
13+
rest.post('https://example.com/echo', (req, res, ctx) =>
1414
res(ctx.json({ ...req, headers: req.headers.getAllHeaders() }))
1515
),
1616

packages/toolkit/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"axios": "^0.19.2",
4848
"console-testing-library": "^0.3.1",
4949
"convert-source-map": "^1.7.0",
50-
"cross-fetch": "^3.1.4",
5150
"esbuild": "^0.11.13",
5251
"eslint": "^7.25.0",
5352
"eslint-config-prettier": "^8.3.0",

packages/toolkit/src/query/fetchBaseQuery.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ export type FetchBaseQueryArgs = {
113113
baseUrl?: string
114114
prepareHeaders?: (
115115
headers: Headers,
116-
api: Pick<BaseQueryApi, 'getState' | 'endpoint' | 'type' | 'forced'>
116+
api: Pick<
117+
BaseQueryApi,
118+
'getState' | 'extra' | 'endpoint' | 'type' | 'forced'
119+
>
117120
) => MaybePromise<Headers>
118121
fetchFn?: (
119122
input: RequestInfo,
@@ -144,20 +147,20 @@ export type FetchBaseQueryMeta = { request: Request; response?: Response }
144147
*
145148
* @param {string} baseUrl
146149
* The base URL for an API service.
147-
* Typically in the format of http://example.com/
150+
* Typically in the format of https://example.com/
148151
*
149-
* @param {(headers: Headers, api: { getState: () => unknown }) => Headers} prepareHeaders
152+
* @param {(headers: Headers, api: { getState: () => unknown; extra: unknown; endpoint: string; type: 'query' | 'mutation'; forced: boolean; }) => Headers} prepareHeaders
150153
* An optional function that can be used to inject headers on requests.
151-
* Provides a Headers object, as well as the `getState` function from the
152-
* redux store. Can be useful for authentication.
154+
* Provides a Headers object, as well as most of the `BaseQueryApi` (`dispatch` is not available).
155+
* Useful for setting authentication or headers that need to be set conditionally.
153156
*
154157
* @link https://developer.mozilla.org/en-US/docs/Web/API/Headers
155158
*
156159
* @param {(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>} fetchFn
157160
* Accepts a custom `fetch` function if you do not want to use the default on the window.
158161
* Useful in SSR environments if you need to use a library such as `isomorphic-fetch` or `cross-fetch`
159162
*
160-
* @param {(params: Record<string, unknown> => string} paramsSerializer
163+
* @param {(params: Record<string, unknown>) => string} paramsSerializer
161164
* An optional function that can be used to stringify querystring parameters.
162165
*/
163166
export function fetchBaseQuery({
@@ -178,7 +181,8 @@ export function fetchBaseQuery({
178181
'Warning: `fetch` is not available. Please supply a custom `fetchFn` property to use `fetchBaseQuery` on SSR environments.'
179182
)
180183
}
181-
return async (arg, { signal, getState, endpoint, forced, type }) => {
184+
return async (arg, api) => {
185+
const { signal, getState, extra, endpoint, forced, type } = api
182186
let meta: FetchBaseQueryMeta | undefined
183187
let {
184188
url,
@@ -200,7 +204,7 @@ export function fetchBaseQuery({
200204

201205
config.headers = await prepareHeaders(
202206
new Headers(stripUndefined(headers)),
203-
{ getState, endpoint, forced, type }
207+
{ getState, extra, endpoint, forced, type }
204208
)
205209

206210
// Only set the content-type to json if appropriate. Will not be true for FormData, ArrayBuffer, Blob, etc.

packages/toolkit/src/query/tests/buildHooks.test.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1751,11 +1751,11 @@ describe('hooks with createApi defaults set', () => {
17511751
posts = [...initialPosts]
17521752

17531753
const handlers = [
1754-
rest.get('http://example.com/posts', (req, res, ctx) => {
1754+
rest.get('https://example.com/posts', (req, res, ctx) => {
17551755
return res(ctx.json(posts))
17561756
}),
17571757
rest.put<Partial<Post>>(
1758-
'http://example.com/post/:id',
1758+
'https://example.com/post/:id',
17591759
(req, res, ctx) => {
17601760
const id = Number(req.params.id)
17611761
const idx = posts.findIndex((post) => post.id === id)
@@ -1775,7 +1775,7 @@ describe('hooks with createApi defaults set', () => {
17751775
return res(ctx.json(posts))
17761776
}
17771777
),
1778-
rest.post('http://example.com/post', (req, res, ctx) => {
1778+
rest.post('https://example.com/post', (req, res, ctx) => {
17791779
let post = req.body as Omit<Post, 'id'>
17801780
startingId += 1
17811781
posts.concat({
@@ -1799,7 +1799,7 @@ describe('hooks with createApi defaults set', () => {
17991799
type PostsResponse = Post[]
18001800

18011801
const api = createApi({
1802-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com/' }),
1802+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com/' }),
18031803
tagTypes: ['Posts'],
18041804
endpoints: (build) => ({
18051805
getPosts: build.query<PostsResponse, void>({

packages/toolkit/src/query/tests/cacheCollection.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ beforeEach(() => {
1616
test(`query: await cleanup, defaults`, async () => {
1717
const { store, api } = storeForApi(
1818
createApi({
19-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
19+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
2020
endpoints: (build) => ({
2121
query: build.query<unknown, string>({
2222
query: () => '/success',
@@ -35,7 +35,7 @@ test(`query: await cleanup, defaults`, async () => {
3535
test(`query: await cleanup, keepUnusedDataFor set`, async () => {
3636
const { store, api } = storeForApi(
3737
createApi({
38-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
38+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
3939
endpoints: (build) => ({
4040
query: build.query<unknown, string>({
4141
query: () => '/success',
@@ -55,7 +55,7 @@ test(`query: await cleanup, keepUnusedDataFor set`, async () => {
5555
describe(`query: await cleanup, keepUnusedDataFor set`, () => {
5656
const { store, api } = storeForApi(
5757
createApi({
58-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
58+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
5959
endpoints: (build) => ({
6060
query: build.query<unknown, string>({
6161
query: () => '/success',

packages/toolkit/src/query/tests/cacheLifecycle.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ beforeAll(() => {
88
})
99

1010
const api = createApi({
11-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
11+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
1212
endpoints: () => ({}),
1313
})
1414
const storeRef = setupApiStore(api)

packages/toolkit/src/query/tests/createApi.test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ describe('additional transformResponse behaviors', () => {
505505
type SuccessResponse = { value: 'success' }
506506
type EchoResponseData = { banana: 'bread' }
507507
const api = createApi({
508-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
508+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
509509
endpoints: (build) => ({
510510
echo: build.mutation({
511511
query: () => ({ method: 'PUT', url: '/echo' }),
@@ -543,7 +543,7 @@ describe('additional transformResponse behaviors', () => {
543543
query: build.query<SuccessResponse & EchoResponseData, void>({
544544
query: () => '/success',
545545
transformResponse: async (response: SuccessResponse) => {
546-
const res = await fetch('http://example.com/echo', {
546+
const res = await fetch('https://example.com/echo', {
547547
method: 'POST',
548548
body: JSON.stringify({ banana: 'bread' }),
549549
}).then((res) => res.json())
@@ -642,7 +642,7 @@ describe('query endpoint lifecycles - onStart, onSuccess, onError', () => {
642642

643643
type SuccessResponse = { value: 'success' }
644644
const api = createApi({
645-
baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }),
645+
baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
646646
endpoints: (build) => ({
647647
echo: build.mutation({
648648
query: () => ({ method: 'PUT', url: '/echo' }),
@@ -679,7 +679,7 @@ describe('query endpoint lifecycles - onStart, onSuccess, onError', () => {
679679
test('query lifecycle events fire properly', async () => {
680680
// We intentionally fail the first request so we can test all lifecycles
681681
server.use(
682-
rest.get('http://example.com/success', (_, res, ctx) =>
682+
rest.get('https://example.com/success', (_, res, ctx) =>
683683
res.once(ctx.status(500), ctx.json({ value: 'failed' }))
684684
)
685685
)
@@ -703,7 +703,7 @@ describe('query endpoint lifecycles - onStart, onSuccess, onError', () => {
703703
test('mutation lifecycle events fire properly', async () => {
704704
// We intentionally fail the first request so we can test all lifecycles
705705
server.use(
706-
rest.post('http://example.com/success', (_, res, ctx) =>
706+
rest.post('https://example.com/success', (_, res, ctx) =>
707707
res.once(ctx.status(500), ctx.json({ value: 'failed' }))
708708
)
709709
)

packages/toolkit/src/query/tests/devWarnings.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ afterEach(() => {
2020
restore()
2121
})
2222

23-
const baseUrl = 'http://example.com'
23+
const baseUrl = 'https://example.com'
2424

2525
function createApis() {
2626
const api1 = createApi({

0 commit comments

Comments
 (0)