Skip to content

Commit

Permalink
feat: client側のfetch追加
Browse files Browse the repository at this point in the history
  • Loading branch information
mdkk11 committed Sep 23, 2024
1 parent 3378d78 commit da60053
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/features/weather/services/forecast/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ForecastWeatherData } from "@/features/weather/models"

import { fetchWrapper } from "../helper"

export type DayRange = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14

/**
* 最大14日間の天気予報と天気アラートを取得する
* @see https://app.swaggerhub.com/apis-docs/WeatherAPI.com/WeatherAPI/1.0.2#/APIs/forecast-weather
* @param q - 郵便番号(アメリカ、イギリス、カナダのみ)、IPアドレス、緯度経度(10進法)、都市名
* @param days - 天気予報の日数。1~14
*/
export const fetchForecastWeather = (q: string, days: DayRange) => {
const params = new URLSearchParams({
q,
days: days.toString(),
})
return fetchWrapper<ForecastWeatherData>(`/api/forecast?${params}`)
}
49 changes: 49 additions & 0 deletions src/features/weather/services/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const errors = {
400: { message: "Bad Request", status: 400 },
401: { message: "Unauthorized", status: 401 },
404: { message: "Not Found", status: 404 },
409: { message: "Conflict", status: 409 },
500: { message: "Internal Server Error", status: 500 },
}

type ErrorStatus = keyof typeof errors

class FetchError extends Error {
status: number
constructor(message: string, status: number) {
super(message)
this.name = "FetchError"
this.status = status
}
}

export const fetchWrapper = async <T>(url: string, options: RequestInit = {}): Promise<T> => {
try {
const response = await fetch(url, options)

if (!response.ok) {
const errorStatus = response.status

const error = isErrorStatus(errorStatus)
? errors[errorStatus]
: { message: "Unknown Error", status: response.status }
throw new FetchError(error.message, error.status)
}

const data = await response.json()

return data
} catch (error) {
if (error instanceof FetchError) {
throw error
} else if (error instanceof Error) {
throw new FetchError("Network error or other error occurred", 500)
} else {
throw new FetchError("An unknown error occurred", 500)
}
}
}

function isErrorStatus(status: number): status is ErrorStatus {
return Object.prototype.hasOwnProperty.call(errors, status)
}
2 changes: 2 additions & 0 deletions src/features/weather/services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./forecast"
export * from "./search"
16 changes: 16 additions & 0 deletions src/features/weather/services/search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { LocationData } from "@/features/weather/models"

import { fetchWrapper } from "../helper"

/**
* マッチした市区町村を Location オブジェクトの配列として返す
* @see https://app.swaggerhub.com/apis-docs/WeatherAPI.com/WeatherAPI/1.0.2#/APIs/search-autocomplete-weather
* @param q - 郵便番号(アメリカ、イギリス、カナダのみ)、IPアドレス、緯度経度(10進法)、都市名
*/
export const fetchMatchedLocation = (q: string) => {
const params = new URLSearchParams({
q,
})

return fetchWrapper<LocationData>(`/api/search?${params}`)
}

0 comments on commit da60053

Please sign in to comment.