summaryrefslogtreecommitdiff
path: root/app/services/api/api.ts
diff options
context:
space:
mode:
authorThomas F. K. Jorna <[email protected]>2021-07-14 15:10:31 +0200
committerThomas F. K. Jorna <[email protected]>2021-07-14 15:10:31 +0200
commite5021187e96b78b53203bd95d08d6818aea47d17 (patch)
tree37ec45d00eb963db53cd4bb4f04a770414b351cc /app/services/api/api.ts
New Ignite 7.0.6 app
Diffstat (limited to 'app/services/api/api.ts')
-rw-r--r--app/services/api/api.ts102
1 files changed, 102 insertions, 0 deletions
diff --git a/app/services/api/api.ts b/app/services/api/api.ts
new file mode 100644
index 0000000..15f6815
--- /dev/null
+++ b/app/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" }
+ }
+ }
+}