Skip to content

Commit

Permalink
feat(axios): implement etag functionality (#765)
Browse files Browse the repository at this point in the history
* chore(axios): upgrade axios to 0.24 and add axios cache interceptor

pin axios to only allow minor patch upgrades, and pin the version of interceptor exactly. this is
because there is a support table
[here](https://axios-cache-interceptor.js.org/guide/getting-started) that lists the compat and we
require at least 0.6.x for ETag support. in order to prevent versioning errors (0.8.4 of interceptor
works wtih 0.25 of axios!!), we will pin the exact version of interceptor + patch version of axios

* feat(axiosinstance): add initialisation code

* chore(package): lock versions

* fix(axiosinstance): update config for cache interceptor
  • Loading branch information
seaerchin authored and alexanderleegs committed May 19, 2023
1 parent b74434b commit 5b0a50f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 17 deletions.
57 changes: 52 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"auto-bind": "^4.0.0",
"aws-lambda": "^1.0.7",
"aws-sdk": "^2.946.0",
"axios": "^0.21.3",
"axios": "~0.25.0",
"axios-cache-interceptor": "^0.9.2",
"base-64": "^0.1.0",
"bcrypt": "^5.1.0",
"bluebird": "^3.7.2",
Expand Down
35 changes: 24 additions & 11 deletions src/services/api/AxiosInstance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import axios, { AxiosRequestConfig, AxiosResponse } from "axios"
import { setupCache } from "axios-cache-interceptor"

import { config } from "@config/config"

Expand All @@ -10,10 +11,10 @@ import tracer from "@utils/tracer"
// Env vars
const GITHUB_ORG_NAME = config.get("github.orgName")

const requestFormatter = async (config: AxiosRequestConfig) => {
const requestFormatter = async (axiosConfig: AxiosRequestConfig) => {
logger.info("Making GitHub API call")

const authMessage = config.headers.Authorization
const authMessage = axiosConfig.headers?.Authorization

// If accessToken is missing, authMessage is `token `
// NOTE: This also implies that the user has not provided
Expand All @@ -25,15 +26,17 @@ const requestFormatter = async (config: AxiosRequestConfig) => {

if (isEmailLoginUser) {
const accessToken = await getAccessToken()
config.headers.Authorization = `token ${accessToken}`
axiosConfig.headers = {
Authorization: `token ${accessToken}`,
}
tracer.use("http", {
hooks: {
request: (span, req, res) => {
span?.setTag("user.type", "email")
},
},
})
logger.info(`Email login user made call to Github API: ${config.url}`)
logger.info(`Email login user made call to Github API: ${axiosConfig.url}`)
} else {
tracer.use("http", {
hooks: {
Expand All @@ -42,21 +45,25 @@ const requestFormatter = async (config: AxiosRequestConfig) => {
},
},
})
logger.info(`Github login user made call to Github API: ${config.url}`)
logger.info(`Github login user made call to Github API: ${axiosConfig.url}`)
}
return {
...config,
...axiosConfig,
headers: {
"Content-Type": "application/json",
...config.headers,
...axiosConfig.headers,
},
}
}

const respHandler = (response: AxiosResponse) => {
// Any status code that lie within the range of 2xx will cause this function to trigger
const GITHUB_API_LIMIT = 5000
const remainingRequests = response.headers["x-ratelimit-remaining"]
const remainingRequests =
// NOTE: This raises an alarm if the header is missing
// or if the header is not a number.
// This is because the header should always be present.
parseInt(response.headers["x-ratelimit-remaining"], 10) || 0
if (remainingRequests < GITHUB_API_LIMIT * 0.2) {
logger.info("80% of access token capacity reached")
} else if (remainingRequests < GITHUB_API_LIMIT * 0.4) {
Expand All @@ -65,9 +72,15 @@ const respHandler = (response: AxiosResponse) => {
return response
}

const isomerRepoAxiosInstance = axios.create({
baseURL: `https://api.github.com/repos/${GITHUB_ORG_NAME}/`,
})
const isomerRepoAxiosInstance = setupCache(
axios.create({
baseURL: `https://api.github.com/repos/${GITHUB_ORG_NAME}/`,
}),
{
interpretHeader: true,
etag: true,
}
)
isomerRepoAxiosInstance.interceptors.request.use(requestFormatter)
isomerRepoAxiosInstance.interceptors.response.use(respHandler)

Expand Down

0 comments on commit 5b0a50f

Please sign in to comment.