Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions apps/api/src/services/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,24 @@ import type {

dotenv.config();

const GH_PAT = process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
const getGithubPersonalAccessToken = () => {
const token = process.env.GITHUB_PERSONAL_ACCESS_TOKEN?.trim();

const graphqlWithAuth = graphql.defaults({
headers: {
authorization: `token ${GH_PAT}`,
},
});
if (!token) {
throw new Error(
"GITHUB_PERSONAL_ACCESS_TOKEN is required to fetch GitHub projects. Please configure it in apps/api/.env."
);
}

return token;
};

const createGithubClient = () =>
graphql.defaults({
headers: {
authorization: `token ${getGithubPersonalAccessToken()}`,
},
});

export const projectService = {
/**
Expand Down Expand Up @@ -53,6 +64,7 @@ export const projectService = {
queryParts.push(`fork:true`);

const searchQueryString = queryParts.join(" ");
const graphqlWithAuth = createGithubClient();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid recreating the GitHub client on every request.

Creating a new client instance on every call to fetchGithubProjects violates the connection pooling guideline for external service clients and introduces unnecessary performance overhead. Consider caching the client instance after first creation.

As per coding guidelines: apps/api/src/**/{database,clients,services}/*.{js,ts}: Use connection pooling for database and external service clients.

⚡ Proposed fix to cache the client instance
+let cachedClient: ReturnType<typeof graphql.defaults> | null = null;
+
-const createGithubClient = () =>
-  graphql.defaults({
-    headers: {
-      authorization: `token ${getGithubPersonalAccessToken()}`,
-    },
-  });
+const createGithubClient = () => {
+  if (!cachedClient) {
+    const token = getGithubPersonalAccessToken();
+    cachedClient = graphql.defaults({
+      headers: {
+        authorization: `token ${token}`,
+      },
+    });
+  }
+  return cachedClient;
+};

This approach validates the token on first call and reuses the client for subsequent requests, improving performance while maintaining clear error handling.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/services/project.service.ts` at line 67, The code currently
calls createGithubClient() inside fetchGithubProjects, recreating
graphqlWithAuth on every request; change this by introducing a module-scoped
cached client (e.g., a let cachedGraphqlWithAuth) and modify fetchGithubProjects
to initialize cachedGraphqlWithAuth = createGithubClient() only if it’s
undefined or if the token changed/invalid, otherwise reuse the cached instance;
ensure token validation and clear error handling during first creation so
subsequent calls use the pooled client instead of recreating graphqlWithAuth
each time.


const response: GraphQLResponseProps = await graphqlWithAuth(
`
Expand Down