-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pullrequests/:id
route to fetch PRs of a given id
of user using GitHub API
#90
Add pullrequests/:id
route to fetch PRs of a given id
of user using GitHub API
#90
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @swarajpure ,
Please make changes as requested.
utils/getGithubId.js
Outdated
const getGithubId = async (id) => { | ||
try { | ||
const details = await userQuery.fetchUser(id) | ||
return (details.user.github_id) | ||
} catch (err) { | ||
logger.error(`Error while fetching user: ${err}`) | ||
throw err | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to write this function.
You can directly use already existing getUser
function from userController
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@swarajpure @whyDontI Maybe that function should be moved into utils
for better visibility for reusability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ankushdharkar there are more functions related to users in userController, do we need to move all of them in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not required. The user data is already fetched and can be accessed with req.userdata
.
Refer: https://github.com/Real-Dev-Squad/website-backend/blob/develop/middlewares/authenticate.js#L38
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserController is separate because all the user related functions are there. We should import functions from there to where ever we need to use it.
I don't think we should to create a separate function just to access one key (github_id).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ankurnarkhede That is only true for logged in user, here we need user details with ID
data.items.forEach((res) => { | ||
allPRs.push({ | ||
title: res.title, | ||
url: res.url, | ||
state: res.state, | ||
created_at: res.created_at, | ||
updated_at: res.updated_at, | ||
ready_for_review: res.state === 'closed' ? false : !res.draft, | ||
labels: res.labels, | ||
assignees: res.assignees | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can destructure the res
object.
Use shorthand syntax.
const pullRequests = async (req, res) => { | ||
try { | ||
const githubId = await getGithubId(req.params.id) | ||
const url = `https://api.github.com/search/issues?q=org:Real-Dev-Squad+author:${githubId}+type:pr` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set BASE_URL= https://api.github.com
at the starting of the code and reuse the BASE_URL variable whenever you please to generate the full path.
|
||
const pullRequests = async (req, res) => { | ||
try { | ||
const githubId = await getGithubId(req.params.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directly use already existing getUser function from userController
utils/getGithubId.js
Outdated
const getGithubId = async (id) => { | ||
try { | ||
const details = await userQuery.fetchUser(id) | ||
return (details.user.github_id) | ||
} catch (err) { | ||
logger.error(`Error while fetching user: ${err}`) | ||
throw err | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not required. The user data is already fetched and can be accessed with req.userdata
.
Refer: https://github.com/Real-Dev-Squad/website-backend/blob/develop/middlewares/authenticate.js#L38
}) | ||
return res.send(allPRs) | ||
} | ||
return res.send('No pull requests found!') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a JSON response.
const pullRequests = async (req, res) => { | ||
try { | ||
const githubId = await getGithubId(req.params.id) | ||
const url = `https://api.github.com/search/issues?q=org:Real-Dev-Squad+author:${githubId}+type:pr` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the github API URL in the config: https://github.com/Real-Dev-Squad/website-backend/blob/develop/config/default.js#L18
The org name also should be added in the config.
return res.send('No pull requests found!') | ||
} catch (err) { | ||
logger.error(`Error while fetching pull requests: ${err}`) | ||
return res.boom.serverUnavailable('Something went wrong please contact admin') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return 500.
config/development.js
Outdated
@@ -10,6 +10,11 @@ module.exports = { | |||
enableFileLogs: false, | |||
enableConsoleLogs: true, | |||
|
|||
githubApi: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We dont need to add this to development and test config unless the values are changing.
try { | ||
const BASE_URL = 'https://api.github.com' | ||
const { user } = await fetchUser(req.params.id) | ||
const url = `${BASE_URL}/search/issues?q=org:Real-Dev-Squad+author:${user.github_id}+type:pr` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will be using the github API functionality at multiple places in the code.
We better move the PRs fetch logic to a file, say services/githubService.js
where we can add all other logic around fetching data from github.
Also the getNames
function at https://github.com/Real-Dev-Squad/website-backend/pull/90/files#diff-3c24610be60a29530abbeabee1a488714820262747d9542ecd1f39e29d89139aR8 does not necessarily be defined in a separate file unless that's going to be used multiple times in the repo. It can be added in the service function.
@@ -0,0 +1,47 @@ | |||
const logger = require('../utils/logger') | |||
const fetch = require('../lib/fetch') | |||
const config = require('../config') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the library 'config'
, do not read from the file. Refer in other files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should solve the failing CI problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool
const pullRequests = async (req, res) => { | ||
try { | ||
const { user } = await fetchUser(req.params.id) | ||
const url = `${config.baseUrl}/search/issues?q=org:${config.org}+author:${user.github_id}+type:pr` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use check the rate limit rules and also pass the client secret and client Id.
https://developer.github.com/v3/search/#rate-limit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added authorization via personal access token
https://docs.github.com/en/free-pro-team@latest/rest/guides/getting-started-with-the-rest-api#authentication
They have not mentioned how to authorize using client id and client secret
const getPullRequests = async (req, res) => { | ||
try { | ||
const { user } = await fetchUser(req.params.id) | ||
const url = `${config.githubApi.baseUrl}/search/issues?q=org:${config.githubApi.org}+author:${user.github_id}+type:pr` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As used elsewhere, use config.get('')
try { | ||
const { user } = await fetchUser(req.params.id) | ||
const url = `${config.githubApi.baseUrl}/search/issues?q=org:${config.githubApi.org}+author:${user.github_id}+type:pr` | ||
const { data } = await githubService.fetch(url) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the fetch function moved to githubService?
As per we discussed, we were to move it to /utils directory.
Also, the API call should be made from githubService file as per mentioned in the comment: #90 (comment)
The controller should handle any response modifications and error handling.
}) | ||
return res.json(allPRs) | ||
} | ||
return res.json('No pull requests found!') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should send an empty array in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done with requested changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small changes requested, Rest all looks great 👍🏽
services/githubService.js
Outdated
const { data } = await fetch(url) | ||
return data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: What if we directly return fetch call, and destructure the data at call site?
@ankurnarkhede @swarajpure
Anyway TailCallOptimization
will be there, but at call site we are using await, which is not required because we are returning data
directly, not a promise.
What's ideal in this case ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have returned fetch call and destructured the data at function call
And about your second question, we need to use await at function call, otherwise data.total_count
is undefined because data
is not returned yet.
data.items.forEach(({ title, html_url: htmlUrl, state, created_at: createdAt, updated_at: updatedAt, draft, labels, assignees }) => { | ||
const allAssignees = getNames(assignees, 'login') | ||
const allLabels = getNames(labels, 'name') | ||
allPRs.push({ | ||
title: title, | ||
url: htmlUrl, | ||
state: state, | ||
created_at: createdAt, | ||
updated_at: updatedAt, | ||
ready_for_review: state === 'closed' ? false : !draft, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
snake_case -> camelCase -> snake_case
conversion detected.
Any particular reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Fixed it.
…some changes in response
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work Swaraj. 🥳
Once you are done with the GitHub Auth changes, we can merge this PR. 👍🏽
githubOauth: { | ||
clientId: 'GITHUB_CLIENT_ID', | ||
clientSecret: 'GITHUB_CLIENT_SECRET' | ||
clientSecret: 'GITHUB_CLIENT_SECRET', | ||
accessToken: '<accessToken>' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WHat is the access token? And how do we get it? Aren't we using client Id and client secret for making requests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please refer my reply to your earlier review
Posted on discord as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Authorizing now using clientId and clientSecret. Please check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work @swarajpure !
pullrequests/:id
route
pullrequests/:id
routepullrequests/:id
route to fetch PRs of a given id
of user using GitHub API
Added pullrequests/:id API route
Fixes #89
To do[ JSDoc ][ Swagger Annotations ]Please suggest changes, if any.
Thank you!
Subsequent PRs:
username
instead ofid
in pullrequests and other APIs Changed API routes and functions to takeusername
of user along withid
#95/pullrequests
API and write integration tests for them #326