Skip to content

Commit

Permalink
Merge pull request #10 from ks6088ts-labs/feature/issue-9_api-client-…
Browse files Browse the repository at this point in the history
…util

api service for product
  • Loading branch information
ks6088ts authored Jan 3, 2023
2 parents 7a6f0d3 + 998fdfa commit 077df88
Show file tree
Hide file tree
Showing 11 changed files with 2,502 additions and 1 deletion.
369 changes: 369 additions & 0 deletions db.json

Large diffs are not rendered by default.

1,946 changes: 1,945 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"json-server": "json-server --watch db.json --port 5000",
"dev": "next dev",
"build": "next build",
"start": "next start",
Expand Down Expand Up @@ -31,6 +32,7 @@
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"json-server": "^0.17.1",
"prettier": "^2.8.1",
"typescript-eslint": "^0.0.1-alpha.0"
}
Expand Down
25 changes: 25 additions & 0 deletions src/pages/apiHello.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useState, useEffect } from 'react'
import getAllProducts from 'services/products/get-all-products'
import getProduct from 'services/products/get-product'

const ApiHello = () => {
const [data, setData] = useState({ name: '' })
Expand All @@ -8,6 +10,29 @@ const ApiHello = () => {
.then((profile) => {
setData(profile)
})
getProduct(
{
apiRootUrl: 'http://localhost:5000',
},
{
id: 1,
},
)
.then((res) => console.log(res))
.catch((error) => {
console.error('通信に失敗しました', error)
})

getAllProducts(
{
apiRootUrl: 'http://localhost:5000',
},
{},
)
.then((res) => console.log(res))
.catch((error) => {
console.error('通信に失敗しました', error)
})
}, [])
return <div>hello {data.name}</div>
}
Expand Down
77 changes: 77 additions & 0 deletions src/services/products/get-all-products.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type { ApiContext, Category, Condition, Product } from 'types'
import { fetcher } from 'utils'

export type GetAllProductsParams = {
/**
* 商品カテゴリ
*/
category?: Category
/**
* 商品状態
*/
conditions?: Condition[]
/**
* 所有するユーザーID
*/
userId?: number
/**
* ソートするキー
*/
sort?: keyof Omit<Product, 'owner'>
/**
* 昇順or降順
*/
order?: 'asc' | 'desc'
/**
* 取得数
*/
limit?: number
/**
* ページ数
*/
page?: number
}

/**
* プロダクトAPI(一覧取得)
* @param context APIコンテキスト
* @param params 検索条件
* @returns 商品一覧
*/
// eslint-disable-next-line complexity
const getAllProducts = async (
context: ApiContext,
{
category,
conditions,
userId,
page,
limit,
sort = 'id',
order = 'desc',
}: GetAllProductsParams = {},
): Promise<Product[]> => {
const path = `${context.apiRootUrl.replace(/\/$/g, '')}/products`
const params = new URLSearchParams()

category && params.append('category', category)
conditions &&
conditions.forEach((condition) => params.append('condition', condition))
userId && params.append('owner.id', `${userId}`)
page && params.append('_page', `${page}`)
limit && params.append('_limit', `${limit}`)
sort && params.append('_sort', sort)
order && params.append('_order', order)
const query = params.toString()

return await fetcher(query.length > 0 ? `${path}?${query}` : path, {
headers: {
Origin: '*',
Accept: 'application/json',
'Content-Type': 'application/json',
credentials: 'include',
},
})
}

export default getAllProducts
33 changes: 33 additions & 0 deletions src/services/products/get-product.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { ApiContext, Product } from 'types'
import { fetcher } from 'utils'

export type GetProductParams = {
/**
* 取得する商品
*/
id: number
}

/**
* プロダクトAPI(個別取得)
* @param context APIコンテキスト
* @param params 商品ID
* @returns 商品
*/
const getProduct = async (
context: ApiContext,
{ id }: GetProductParams,
): Promise<Product> => {
return await fetcher(
`${context.apiRootUrl.replace(/\/$/g, '')}/products/${id}`,
{
headers: {
Origin: '*',
Accept: 'application/json',
'Content-Type': 'application/json',
},
},
)
}

export default getProduct
32 changes: 32 additions & 0 deletions src/types/data.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 商品カテゴリ
export type Category = 'shoes' | 'clothes' | 'book'
// 商品の状態
export type Condition = 'new' | 'used'

// ユーザー
export type User = {
id: number
username: string
displayName: string
email: string
profileImageUrl: string
description: string
}

// 商品
export type Product = {
id: number
category: Category
title: string
description: string
imageUrl: string
blurDataUrl: string
price: number
condition: Condition
owner: User
}

// APIコンテキスト
export type ApiContext = {
apiRootUrl: string
}
1 change: 1 addition & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './data'
16 changes: 16 additions & 0 deletions src/utils/fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const fetcher = async (
resource: RequestInfo,
init?: RequestInit,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Promise<any> => {
const res = await fetch(resource, init)

if (!res.ok) {
const errorRes = await res.json()
const error = new Error(
errorRes.message ?? 'APIリクエスト中にエラーが発生しました',
)
throw error
}
return res.json()
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './fetcher'
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
Expand Down

0 comments on commit 077df88

Please sign in to comment.