summaryrefslogtreecommitdiff
path: root/app_expo/services/api/api.ts
diff options
context:
space:
mode:
authorKirill Rogovoy <[email protected]>2021-07-20 21:24:52 +0300
committerKirill Rogovoy <[email protected]>2021-07-20 21:24:52 +0300
commit5f4611d65e40eae3ca6191a15f68d69ea5a1c4cb (patch)
tree273dfc086444533d86d580961c92ba8d14781a67 /app_expo/services/api/api.ts
parentf0bf4e7afdcd8b02a62be45ab3e7d047ed865a79 (diff)
WIP
Diffstat (limited to 'app_expo/services/api/api.ts')
-rw-r--r--app_expo/services/api/api.ts102
1 files changed, 102 insertions, 0 deletions
diff --git a/app_expo/services/api/api.ts b/app_expo/services/api/api.ts
new file mode 100644
index 0000000..4093d34
--- /dev/null
+++ b/app_expo/services/api/api.ts
@@ -0,0 +1,102 @@
+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' }
+ }
+ }
+}