-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
119 lines (104 loc) · 2.95 KB
/
index.js
File metadata and controls
119 lines (104 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import express from 'express';
import { StatusCodes } from 'http-status-codes';
import swaggerUi from 'swagger-ui-express';
// set up server
const app = express();
const PORT = process.env.PORT || 8000;
// set limits
const MAX_USERS = 5;
const MAX_REPOS = 5;
// cache responses for 5 minutes
const CACHE_CONTROL = 'public, max-age=300';
const PATH_SEARCH_USERS = 'https://api.github.com/search/users';
const BASE_PATH_USERS = 'https://api.github.com/users';
// setup Swagger documentation
const swaggerDocument = {
swagger: '2.0',
info: {
title: 'Github Proxy API',
version: '1.0.0',
},
paths: {
'/search': {
get: {
summary: 'Search Github users and their repositories',
parameters: [
{
name: 'q',
in: 'query',
required: true,
description: 'Github username search query',
type: 'string',
},
],
responses: {
200: {
description: 'Successful Response',
},
500: {
description: 'Internal Server Error',
},
},
},
},
},
};
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
/**
* Fetch users from Github based on search query
* @param {string} query - search query
* @returns {Promise<Array>} - list of Github users
*/
async function fetchGithubUsers(query) {
const response = await fetch(
`${PATH_SEARCH_USERS}?q=${encodeURIComponent(query)}`,
{
headers: { 'Cache-Control': CACHE_CONTROL },
}
);
if (!response.ok) throw new Error('Github API request failed');
const data = await response.json();
return data.items.slice(0, MAX_USERS);
}
/**
* Fetch recent repositories of a Github user
* @param {string} username - Github username
* @returns {Promise<Array>} - list of (max. 5) Github repositories
*/
async function fetchUserRepos(username) {
const repoResponse = await fetch(
`${BASE_PATH_USERS}/${username}/repos?sort=updated&per_page=${MAX_REPOS}`,
{
headers: { 'Cache-Control': CACHE_CONTROL },
}
);
if (!repoResponse.ok) throw new Error('Failed to fetch user repositories');
return await repoResponse.json();
}
/**
* API endpoint to search Github users and their recent repositories
*/
app.get('/search', async (req, res) => {
const { q } = req.query;
try {
const users = await fetchGithubUsers(q);
const enrichedUsers = await Promise.all(
users.map(async (user) => {
const repos = await fetchUserRepos(user.login);
return {
username: user.login,
repos: repos.map((repo) => ({ name: repo.name, url: repo.html_url })),
};
})
);
res.set('Cache-Control', CACHE_CONTROL);
res.status(StatusCodes.OK).json(enrichedUsers);
} catch (error) {
res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.json({ message: error.message });
}
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});