Skip to content

Commit b7da094

Browse files
committed
refactor: clean up fetch from api function
1 parent 9087b42 commit b7da094

File tree

16 files changed

+163
-76
lines changed

16 files changed

+163
-76
lines changed

__tests__/unit/api/api.test.ts

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import { expect, test } from "vitest";
2-
import { fetchFromApi } from "../../../src/api/request";
2+
import { RequestOptions, fetchFromApi } from "../../../src/api/request";
33

44
test("should returns 404 if path contains ignore chars", async () => {
5-
const response = await fetchFromApi(
6-
"https://example.com/hoge.svg",
7-
"",
8-
null,
9-
{
10-
interceptIfContainsIgnorePaths: true
11-
}
12-
);
5+
const options: RequestOptions = {
6+
interceptIfContainsIgnorePaths: true
7+
};
8+
const response = await fetchFromApi("https://example.com/hoge.svg", options);
139
expect(response.status).toEqual(404);
1410
});

src/api/request.ts

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
11
import { RequestContext } from "../models/models";
22
import { isMatch } from "../utils/match";
33

4+
export type RequestOptions = {
5+
headers?: object;
6+
queryParams?: string;
7+
interceptIfContainsIgnorePaths?: boolean;
8+
};
9+
410
// TODO: write test code
511
// TODO: more simply
612
export async function fetchFromApi(
713
endpoint: string,
8-
queryParams: string = "",
9-
ctx: RequestContext | null,
10-
options: {
11-
interceptIfContainsIgnorePaths: boolean;
12-
} | null = null
14+
{
15+
headers = {},
16+
queryParams = "",
17+
interceptIfContainsIgnorePaths = false
18+
}: RequestOptions = {}
1319
): Promise<Response> {
14-
// TODO: extract to function & write test code
15-
if (options) {
16-
if (options.interceptIfContainsIgnorePaths) {
17-
if (!endpoint || (endpoint && isMatch(endpoint))) {
18-
return new Response(null, { status: 404 });
19-
}
20+
if (interceptIfContainsIgnorePaths) {
21+
if (!endpoint || (endpoint && isMatch(endpoint))) {
22+
return new Response(null, { status: 404 });
2023
}
2124
}
2225

23-
const q = queryParams ?? "";
24-
const url = buildRequestUrl(endpoint, q);
25-
const header = ctx ? { header: requestHeaderFrom(ctx) } : {};
26+
const url = buildRequestUrl(endpoint, queryParams);
27+
const header = headers ? { header: headers } : {};
2628

2729
return fetch(url, {
2830
method: "GET",
@@ -37,7 +39,7 @@ export function buildRequestUrl(url: string, queryParams: string): string {
3739
return new URL(u).href;
3840
}
3941

40-
function requestHeaderFrom(rq: RequestContext): Object {
42+
export function requestHeaderFrom(rq: RequestContext): Object {
4143
return {
4244
"Content-Type": "application/json",
4345
"x-forwarded-for": rq.ipAddress,

src/app/[...slug]/page.tsx

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { headers } from "next/headers";
55
import { permanentRedirect } from "next/navigation";
66
import { cache } from "react";
77
import { api } from "../../../config";
8-
import { fetchFromApi } from "../../api/request";
8+
import {
9+
RequestOptions,
10+
fetchFromApi,
11+
requestHeaderFrom
12+
} from "../../api/request";
913
import {
1014
Content,
1115
ContentResponse,
@@ -20,13 +24,15 @@ import { Renderer } from "./renderer";
2024

2125
// TODO: move somewhere if possible
2226
const cachedFindByPath = cache(async (path: string) => {
23-
const ctx = requestContextFrom(headers());
2427
// TODO: devide into another `function` and move `api` dir.
2528
const slug = sluggize(["v1", "contents", path]);
2629
const url = buildUrl(api.url, slug, true);
27-
const response = await fetchFromApi(url, null, ctx, {
30+
const ctx = requestContextFrom(headers());
31+
const options: RequestOptions = {
32+
headers: requestHeaderFrom(ctx),
2833
interceptIfContainsIgnorePaths: true
29-
});
34+
};
35+
const response = await fetchFromApi(url, options);
3036
throwIfError(response);
3137
const content = (await response.json()) as ContentResponse;
3238
return {

src/app/archives/page.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import { headers } from "next/headers";
44
import { api } from "../../../config";
5-
import { fetchFromApi } from "../../api/request";
5+
import {
6+
RequestOptions,
7+
fetchFromApi,
8+
requestHeaderFrom
9+
} from "../../api/request";
610
import { Archive, ArchiveResponse } from "../../models/models";
711
import { requestContextFrom } from "../../utils/requestContext";
812
import { buildUrl } from "../../utils/url";
@@ -19,10 +23,13 @@ async function run(req: any): Promise<any> {
1923
}
2024

2125
async function handler(req: any) {
22-
const ctx = requestContextFrom(headers());
2326
// TODO: devide into another `function` and move `api` dir.
2427
const url = buildUrl(api.url, "v1/archives", true);
25-
const response: Response = await fetchFromApi(url, null, ctx, null);
28+
const ctx = requestContextFrom(headers());
29+
const options: RequestOptions = {
30+
headers: requestHeaderFrom(ctx)
31+
};
32+
const response: Response = await fetchFromApi(url, options);
2633
throwIfError(response);
2734

2835
const archiveResponse: Array<ArchiveResponse> =

src/app/articles/[...slug]/page.tsx

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { headers } from "next/headers";
55
import { notFound } from "next/navigation";
66
import { cache } from "react";
77
import { api } from "../../../../config";
8-
import { fetchFromApi } from "../../../api/request";
8+
import {
9+
RequestOptions,
10+
fetchFromApi,
11+
requestHeaderFrom
12+
} from "../../../api/request";
913
import {
1014
Content,
1115
ContentResponse,
@@ -23,13 +27,15 @@ const PREFIX_URL = "articles";
2327

2428
// TODO: move somewhere if possible
2529
const cachedFindByPath = cache(async (path: string) => {
26-
const ctx = requestContextFrom(headers());
2730
// TODO: devide into another `function` and move `api` dir.
2831
const slug = sluggize(["v1", "contents", path]);
2932
const url = buildUrl(api.url, slug, true);
30-
const response = await fetchFromApi(url, null, ctx, {
33+
const ctx = requestContextFrom(headers());
34+
const options: RequestOptions = {
35+
headers: requestHeaderFrom(ctx),
3136
interceptIfContainsIgnorePaths: true
32-
});
37+
};
38+
const response = await fetchFromApi(url, options);
3339
throwIfError(response);
3440
const content = (await response.json()) as ContentResponse;
3541
return {

src/app/articles/page.tsx

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import { headers } from "next/headers";
44
import { api } from "../../../config";
5-
import { fetchFromApi } from "../../api/request";
5+
import {
6+
RequestOptions,
7+
fetchFromApi,
8+
requestHeaderFrom
9+
} from "../../api/request";
610
import { Article, ArticleResponseWithCount } from "../../models/models";
711
import { requestContextFrom } from "../../utils/requestContext";
812
import { buildQueryParams, buildUrl } from "../../utils/url";
@@ -20,13 +24,16 @@ async function run(req: any): Promise<any> {
2024

2125
async function handler(req: any) {
2226
const currentPage = req.searchParams["p"] ? req.searchParams["p"] : 1;
23-
const ctx = requestContextFrom(headers());
2427
// TODO: devide into another `function` and move `api` dir.
2528
const url = buildUrl(api.url, "v1/articles", true);
26-
const queryParams = buildQueryParams({
27-
pagination: { page: currentPage, limit: 10 }
28-
});
29-
const response: Response = await fetchFromApi(url, queryParams, ctx, null);
29+
const ctx = requestContextFrom(headers());
30+
const options: RequestOptions = {
31+
headers: requestHeaderFrom(ctx),
32+
queryParams: buildQueryParams({
33+
pagination: { page: currentPage, limit: 10 }
34+
})
35+
};
36+
const response: Response = await fetchFromApi(url, options);
3037
throwIfError(response);
3138

3239
const articlesResponseWithCount: ArticleResponseWithCount =

src/app/feeds/index.xml/route.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import { headers } from "next/headers";
22
import { api, mainAuthor, siteName, url } from "../../../../config";
3-
import { fetchFromApi } from "../../../api/request";
3+
import {
4+
RequestOptions,
5+
fetchFromApi,
6+
requestHeaderFrom
7+
} from "../../../api/request";
48
import { Feed } from "../../../models/models";
59
import { generateFeedsString } from "../../../services/feeds";
610
import { requestContextFrom } from "../../../utils/requestContext";
711
import { buildUrl, sluggize } from "../../../utils/url";
812

913
//export async function get(ctx: any) {
1014
export async function GET() {
11-
const ctx = requestContextFrom(headers());
1215
// TODO: devide into another `function` and move `api` dir.
1316
const apiUrl = buildUrl(api.url, sluggize(["v1", "feeds", "index"]), false);
14-
const response: Response = await fetchFromApi(apiUrl, null, ctx, null);
17+
const ctx = requestContextFrom(headers());
18+
const options: RequestOptions = {
19+
headers: requestHeaderFrom(ctx)
20+
};
21+
const response: Response = await fetchFromApi(apiUrl, options);
1522

1623
if (response.status !== 200) {
1724
/* NOTE:

src/app/page.tsx

+11-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import { headers } from "next/headers";
44
import { api } from "../../config";
5-
import { fetchFromApi } from "../api/request";
5+
import {
6+
RequestOptions,
7+
fetchFromApi,
8+
requestHeaderFrom
9+
} from "../api/request";
610
import { Article, ArticleResponseWithCount } from "../models/models";
711
import { requestContextFrom } from "../utils/requestContext";
812
import { buildQueryParams, buildUrl } from "../utils/url";
@@ -19,11 +23,14 @@ async function run(req: any): Promise<any> {
1923
}
2024

2125
async function handler(req: any) {
22-
const ctx = requestContextFrom(headers());
2326
// TODO: devide into another `function` and move `api` dir.
2427
const url = buildUrl(api.url, "v1/articles", true);
25-
const queryParams = buildQueryParams({ pagination: { page: 1, limit: 5 } });
26-
const response: Response = await fetchFromApi(url, queryParams, ctx, null);
28+
const ctx = requestContextFrom(headers());
29+
const options: RequestOptions = {
30+
headers: requestHeaderFrom(ctx),
31+
queryParams: buildQueryParams({ pagination: { page: 1, limit: 5 } })
32+
};
33+
const response: Response = await fetchFromApi(url, options);
2734
throwIfError(response);
2835

2936
const articlesResponseWithCount: ArticleResponseWithCount =

src/app/search/page.tsx

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import { headers } from "next/headers";
44
import { api } from "../../../config";
5-
import { fetchFromApi } from "../../api/request";
5+
import {
6+
RequestOptions,
7+
fetchFromApi,
8+
requestHeaderFrom
9+
} from "../../api/request";
610
import { SearchResponse, SearchResponseWithCount } from "../../models/models";
711
import { requestContextFrom } from "../../utils/requestContext";
812
import { buildQueryParams, buildUrl, sluggize } from "../../utils/url";
@@ -73,13 +77,16 @@ async function handler(req: any) {
7377
}
7478

7579
async function execute(req, words: Array<string>) {
76-
const ctx = requestContextFrom(headers());
7780
// TODO: devide into another `function` and move `api` dir.
7881
const url = buildUrl(api.url, sluggize(["v1", "search"]), false);
79-
const queryParams = buildQueryParams({
80-
params: { key: "q", values: words }
81-
});
82-
const response = await fetchFromApi(url, queryParams, ctx, null);
82+
const ctx = requestContextFrom(headers());
83+
const options: RequestOptions = {
84+
headers: requestHeaderFrom(ctx),
85+
queryParams: buildQueryParams({
86+
params: { key: "q", values: words }
87+
})
88+
};
89+
const response = await fetchFromApi(url, options);
8390

8491
if (response.status !== 200) {
8592
return emptyResult;

src/app/series/[slug]/page.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import { headers } from "next/headers";
44
import { api } from "../../../../config";
5-
import { fetchFromApi } from "../../../api/request";
5+
import {
6+
RequestOptions,
7+
fetchFromApi,
8+
requestHeaderFrom
9+
} from "../../../api/request";
610
import {
711
Article,
812
SeriresWithArticles,
@@ -23,10 +27,13 @@ async function run(req: any): Promise<any> {
2327
}
2428
async function handler(req: any) {
2529
const seriesName = req.params.slug;
26-
const ctx = requestContextFrom(headers());
2730
// TODO: devide into another `function` and move `api` dir.
2831
const url = buildUrl(api.url, sluggize(["v1", "series", seriesName]), false);
29-
const response: Response = await fetchFromApi(url, null, ctx);
32+
const ctx = requestContextFrom(headers());
33+
const options: RequestOptions = {
34+
headers: requestHeaderFrom(ctx)
35+
};
36+
const response: Response = await fetchFromApi(url, options);
3037
throwIfError(response);
3138

3239
const seriresWithArticlesResponse: SeriresWithArticlesResponse =

src/app/series/page.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import { headers } from "next/headers";
44
import { api } from "../../../config";
5-
import { fetchFromApi } from "../../api/request";
5+
import {
6+
RequestOptions,
7+
fetchFromApi,
8+
requestHeaderFrom
9+
} from "../../api/request";
610
import { Series, SeriesResponse } from "../../models/models";
711
import { requestContextFrom } from "../../utils/requestContext";
812
import { buildUrl, sluggize } from "../../utils/url";
@@ -19,10 +23,13 @@ async function run(req: any): Promise<any> {
1923
}
2024

2125
async function handler(req: any) {
22-
const ctx = requestContextFrom(headers());
2326
// TODO: devide into another `function` and move `api` dir.
2427
const url = buildUrl(api.url, sluggize(["v1", "series"]), true);
25-
const response: Response = await fetchFromApi(url, null, ctx, null);
28+
const ctx = requestContextFrom(headers());
29+
const options: RequestOptions = {
30+
headers: requestHeaderFrom(ctx)
31+
};
32+
const response: Response = await fetchFromApi(url, options);
2633
throwIfError(response);
2734

2835
const seriesResponse: Array<SeriesResponse> =

src/app/sitemap.xml/route.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
import { headers } from "next/headers";
22
import { api } from "../../../config";
3-
import { fetchFromApi } from "../../api/request";
3+
import {
4+
RequestOptions,
5+
fetchFromApi,
6+
requestHeaderFrom
7+
} from "../../api/request";
48
import { Sitemap } from "../../models/models";
59
import { generateSitemapString } from "../../services/sitemap";
610
import { requestContextFrom } from "../../utils/requestContext";
711
import { buildUrl, sluggize } from "../../utils/url";
812

913
export async function GET() {
10-
const ctx = requestContextFrom(headers());
1114
// TODO: devide into another `function` and move `api` dir.
1215
const url = buildUrl(api.url, sluggize(["v1", "sitemaps"]), true);
13-
const response: Response = await fetchFromApi(url, null, ctx, null);
16+
const ctx = requestContextFrom(headers());
17+
const options: RequestOptions = {
18+
headers: requestHeaderFrom(ctx)
19+
};
20+
const response: Response = await fetchFromApi(url, options);
1421

1522
if (response.status !== 200) {
1623
return new Response("", {

0 commit comments

Comments
 (0)