diff options
Diffstat (limited to 'app_expo/services/api')
-rw-r--r-- | app_expo/services/api/api-config.ts | 27 | ||||
-rw-r--r-- | app_expo/services/api/api-problem.test.ts | 100 | ||||
-rw-r--r-- | app_expo/services/api/api-problem.ts | 74 | ||||
-rw-r--r-- | app_expo/services/api/api.ts | 102 | ||||
-rw-r--r-- | app_expo/services/api/api.types.ts | 13 | ||||
-rw-r--r-- | app_expo/services/api/character-api.ts | 37 | ||||
-rw-r--r-- | app_expo/services/api/index.ts | 2 |
7 files changed, 0 insertions, 355 deletions
diff --git a/app_expo/services/api/api-config.ts b/app_expo/services/api/api-config.ts deleted file mode 100644 index b939c0e..0000000 --- a/app_expo/services/api/api-config.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Use this import if you want to use "env.js" file -// const { API_URL } = require("../../config/env") -// Or just specify it directly like this: -const API_URL = 'http://example.com' - -/** - * The options used to configure the API. - */ -export interface ApiConfig { - /** - * The URL of the api. - */ - url: string - - /** - * Milliseconds before we timeout the request. - */ - timeout: number -} - -/** - * The default configuration for the app. - */ -export const DEFAULT_API_CONFIG: ApiConfig = { - url: API_URL || 'https://jsonplaceholder.typicode.com', - timeout: 10000, -} diff --git a/app_expo/services/api/api-problem.test.ts b/app_expo/services/api/api-problem.test.ts deleted file mode 100644 index f8b4041..0000000 --- a/app_expo/services/api/api-problem.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { getGeneralApiProblem } from './api-problem' -import { ApiErrorResponse } from 'apisauce' - -test('handles connection errors', () => { - expect( - getGeneralApiProblem({ - problem: 'CONNECTION_ERROR', - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'cannot-connect', - temporary: true, - }) -}) - -test('handles network errors', () => { - expect( - getGeneralApiProblem({ - problem: 'NETWORK_ERROR', - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'cannot-connect', - temporary: true, - }) -}) - -test('handles timeouts', () => { - expect( - getGeneralApiProblem({ - problem: 'TIMEOUT_ERROR', - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'timeout', - temporary: true, - }) -}) - -test('handles server errors', () => { - expect(getGeneralApiProblem({ problem: 'SERVER_ERROR' } as ApiErrorResponse<null>)).toEqual({ - kind: 'server', - }) -}) - -test('handles unknown errors', () => { - expect( - getGeneralApiProblem({ - problem: 'UNKNOWN_ERROR', - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'unknown', - temporary: true, - }) -}) - -test('handles unauthorized errors', () => { - expect( - getGeneralApiProblem({ - problem: 'CLIENT_ERROR', - status: 401, - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'unauthorized', - }) -}) - -test('handles forbidden errors', () => { - expect( - getGeneralApiProblem({ - problem: 'CLIENT_ERROR', - status: 403, - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'forbidden', - }) -}) - -test('handles not-found errors', () => { - expect( - getGeneralApiProblem({ - problem: 'CLIENT_ERROR', - status: 404, - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'not-found', - }) -}) - -test('handles other client errors', () => { - expect( - getGeneralApiProblem({ - problem: 'CLIENT_ERROR', - status: 418, - } as ApiErrorResponse<null>), - ).toEqual({ - kind: 'rejected', - }) -}) - -test('handles cancellation errors', () => { - expect(getGeneralApiProblem({ problem: 'CANCEL_ERROR' } as ApiErrorResponse<null>)).toBeNull() -}) diff --git a/app_expo/services/api/api-problem.ts b/app_expo/services/api/api-problem.ts deleted file mode 100644 index 15ca850..0000000 --- a/app_expo/services/api/api-problem.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { ApiResponse } from 'apisauce' - -export type GeneralApiProblem = - /** - * Times up. - */ - | { kind: 'timeout'; temporary: true } - /** - * Cannot connect to the server for some reason. - */ - | { kind: 'cannot-connect'; temporary: true } - /** - * The server experienced a problem. Any 5xx error. - */ - | { kind: 'server' } - /** - * We're not allowed because we haven't identified ourself. This is 401. - */ - | { kind: 'unauthorized' } - /** - * We don't have access to perform that request. This is 403. - */ - | { kind: 'forbidden' } - /** - * Unable to find that resource. This is a 404. - */ - | { kind: 'not-found' } - /** - * All other 4xx series errors. - */ - | { kind: 'rejected' } - /** - * Something truly unexpected happened. Most likely can try again. This is a catch all. - */ - | { kind: 'unknown'; temporary: true } - /** - * The data we received is not in the expected format. - */ - | { kind: 'bad-data' } - -/** - * Attempts to get a common cause of problems from an api response. - * - * @param response The api response. - */ -export function getGeneralApiProblem(response: ApiResponse<any>): GeneralApiProblem | void { - switch (response.problem) { - case 'CONNECTION_ERROR': - return { kind: 'cannot-connect', temporary: true } - case 'NETWORK_ERROR': - return { kind: 'cannot-connect', temporary: true } - case 'TIMEOUT_ERROR': - return { kind: 'timeout', temporary: true } - case 'SERVER_ERROR': - return { kind: 'server' } - case 'UNKNOWN_ERROR': - return { kind: 'unknown', temporary: true } - case 'CLIENT_ERROR': - switch (response.status) { - case 401: - return { kind: 'unauthorized' } - case 403: - return { kind: 'forbidden' } - case 404: - return { kind: 'not-found' } - default: - return { kind: 'rejected' } - } - case 'CANCEL_ERROR': - return null - } - - return null -} diff --git a/app_expo/services/api/api.ts b/app_expo/services/api/api.ts deleted file mode 100644 index 4093d34..0000000 --- a/app_expo/services/api/api.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ApisauceInstance, create, ApiResponse } from 'apisauce' -import { getGeneralApiProblem } from './api-problem' -import { ApiConfig, DEFAULT_API_CONFIG } from './api-config' -import * as Types from './api.types' - -/** - * Manages all requests to the API. - */ -export class Api { - /** - * The underlying apisauce instance which performs the requests. - */ - apisauce: ApisauceInstance - - /** - * Configurable options. - */ - config: ApiConfig - - /** - * Creates the api. - * - * @param config The configuration to use. - */ - constructor(config: ApiConfig = DEFAULT_API_CONFIG) { - this.config = config - } - - /** - * Sets up the API. This will be called during the bootup - * sequence and will happen before the first React component - * is mounted. - * - * Be as quick as possible in here. - */ - setup() { - // construct the apisauce instance - this.apisauce = create({ - baseURL: this.config.url, - timeout: this.config.timeout, - headers: { - Accept: 'application/json', - }, - }) - } - - /** - * Gets a list of users. - */ - async getUsers(): Promise<Types.GetUsersResult> { - // make the api call - const response: ApiResponse<any> = await this.apisauce.get(`/users`) - - // the typical ways to die when calling an api - if (!response.ok) { - const problem = getGeneralApiProblem(response) - if (problem) return problem - } - - const convertUser = (raw) => { - return { - id: raw.id, - name: raw.name, - } - } - - // transform the data into the format we are expecting - try { - const rawUsers = response.data - const resultUsers: Types.User[] = rawUsers.map(convertUser) - return { kind: 'ok', users: resultUsers } - } catch { - return { kind: 'bad-data' } - } - } - - /** - * Gets a single user by ID - */ - - async getUser(id: string): Promise<Types.GetUserResult> { - // make the api call - const response: ApiResponse<any> = await this.apisauce.get(`/users/${id}`) - - // the typical ways to die when calling an api - if (!response.ok) { - const problem = getGeneralApiProblem(response) - if (problem) return problem - } - - // transform the data into the format we are expecting - try { - const resultUser: Types.User = { - id: response.data.id, - name: response.data.name, - } - return { kind: 'ok', user: resultUser } - } catch { - return { kind: 'bad-data' } - } - } -} diff --git a/app_expo/services/api/api.types.ts b/app_expo/services/api/api.types.ts deleted file mode 100644 index 21d3c87..0000000 --- a/app_expo/services/api/api.types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { GeneralApiProblem } from './api-problem' -import { Character } from '../../models/character/character' - -export interface User { - id: number - name: string -} - -export type GetUsersResult = { kind: 'ok'; users: User[] } | GeneralApiProblem -export type GetUserResult = { kind: 'ok'; user: User } | GeneralApiProblem - -export type GetCharactersResult = { kind: 'ok'; characters: Character[] } | GeneralApiProblem -export type GetCharacterResult = { kind: 'ok'; character: Character } | GeneralApiProblem diff --git a/app_expo/services/api/character-api.ts b/app_expo/services/api/character-api.ts deleted file mode 100644 index e28ec48..0000000 --- a/app_expo/services/api/character-api.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ApiResponse } from 'apisauce' -import { Api } from './api' -import { GetCharactersResult } from './api.types' -import { getGeneralApiProblem } from './api-problem' - -const API_PAGE_SIZE = 50 - -export class CharacterApi { - private api: Api - - constructor(api: Api) { - this.api = api - } - - async getCharacters(): Promise<GetCharactersResult> { - try { - // make the api call - const response: ApiResponse<any> = await this.api.apisauce.get( - 'https://raw.githubusercontent.com/infinitered/ignite/master/data/rick-and-morty.json', - { amount: API_PAGE_SIZE }, - ) - - // the typical ways to die when calling an api - if (!response.ok) { - const problem = getGeneralApiProblem(response) - if (problem) return problem - } - - const characters = response.data.results - - return { kind: 'ok', characters } - } catch (e) { - __DEV__ && console.tron.log(e.message) - return { kind: 'bad-data' } - } - } -} diff --git a/app_expo/services/api/index.ts b/app_expo/services/api/index.ts deleted file mode 100644 index f133e64..0000000 --- a/app_expo/services/api/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './api' -export * from './api.types' |