From e960ac577e6b9cd6834dc186825e2b003d14a25a Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 00:45:26 +0900 Subject: [PATCH 01/11] Migrate v2 github-user api --- api/src/app/index.ts | 3 ++- api/src/github-user/controller.ts | 33 +++++++++++++++++++++++++ api/src/github-user/types.ts | 17 +++++++++++++ api/src/github/service.ts | 16 ++++++++++++- api/src/github/types.ts | 40 +++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 api/src/github-user/controller.ts create mode 100644 api/src/github-user/types.ts diff --git a/api/src/app/index.ts b/api/src/app/index.ts index 0d182be81..b811c702f 100644 --- a/api/src/app/index.ts +++ b/api/src/app/index.ts @@ -7,6 +7,7 @@ import Container from "typedi"; import { ContributorController } from "../contributor/controller"; import { DocsMiddleware } from "./middlewares/docs"; import { ErrorMiddleware } from "./middlewares/error"; +import { GithubUserController } from "../github-user/controller"; import { LoggerMiddleware } from "./middlewares/logger"; import { LoggerService } from "../logger/service"; import { SecurityMiddleware } from "./middlewares/security"; @@ -18,7 +19,7 @@ useContainer(Container); // Create the app: export const routingControllersOptions = { - controllers: [ContributorController], + controllers: [ContributorController, GithubUserController], middlewares: [ // middlewares: SecurityMiddleware, diff --git a/api/src/github-user/controller.ts b/api/src/github-user/controller.ts new file mode 100644 index 000000000..f61a8bba5 --- /dev/null +++ b/api/src/github-user/controller.ts @@ -0,0 +1,33 @@ +import { Controller, Get, QueryParam } from "routing-controllers"; +import { OpenAPI, ResponseSchema } from "routing-controllers-openapi"; +import { GetUserResponseDto } from "./types"; +import { GithubService } from "../github/service"; +import { GithubUserDto } from "../github/dto"; +import { Service } from "typedi"; +import { plainToClass } from "class-transformer"; + +@Service() +@Controller("/GithubUsers") +export class GithubUserController { + constructor(private readonly githubService: GithubService) {} + + @Get("/") + @OpenAPI({ + summary: "Return a github user with publicly available information", + }) + @ResponseSchema(GetUserResponseDto) + public async getUserByUsername( + @QueryParam("username") username: string, + ): Promise { + const githubUser = await this.githubService.getUser({ + username, + }); + const user = plainToClass(GithubUserDto, { + ...githubUser, + }); + + return { + user, + }; + } +} diff --git a/api/src/github-user/types.ts b/api/src/github-user/types.ts new file mode 100644 index 000000000..3e8395666 --- /dev/null +++ b/api/src/github-user/types.ts @@ -0,0 +1,17 @@ +import {} from "module"; +import { GeneralResponseDto } from "../app/types"; +import { GithubUserDto } from "../github/dto"; +import { Type } from "class-transformer"; +import { ValidateNested } from "class-validator"; + +export class GetContributorsResponseDto extends GeneralResponseDto { + @ValidateNested({ each: true }) + @Type(() => GithubUserDto) + contributors?: GithubUserDto[]; +} + +export class GetUserResponseDto extends GeneralResponseDto { + @ValidateNested({ each: true }) + @Type(() => GithubUserDto) + user?: GithubUserDto; +} diff --git a/api/src/github/service.ts b/api/src/github/service.ts index 63d493776..c72f60620 100644 --- a/api/src/github/service.ts +++ b/api/src/github/service.ts @@ -1,4 +1,9 @@ -import { GeneralGithubQuery, ListContributorsResponse } from "./types"; +import { + GeneralGithubQuery, + GetUserInput, + GitHubUserApiResponse, + ListContributorsResponse, +} from "./types"; import { Service } from "typedi"; import axios from "axios"; @@ -28,5 +33,14 @@ export class GithubService { return contributors; }; + public getUser = async ({ + username, + }: GetUserInput): Promise => { + const response = await axios.get( + `https://api.github.com/users/${username}`, + ); + return response.data; + }; + private apiURL = "https://api.github.com"; } diff --git a/api/src/github/types.ts b/api/src/github/types.ts index 864d5deb0..0f15f0ee8 100644 --- a/api/src/github/types.ts +++ b/api/src/github/types.ts @@ -10,3 +10,43 @@ export interface GeneralGithubQuery { repo: string; path: string; } + +export interface GetUserInput { + username: string; +} + +/* eslint-disable camelcase */ +export interface GitHubUserApiResponse { + login: string; + id: number; + node_id: string; + avatar_url: string; + gravatar_id: string; + url: string; + html_url: string; + followers_url: string; + following_url: string; + gists_url: string; + starred_url: string; + subscriptions_url: string; + organizations_url: string; + repos_url: string; + events_url: string; + received_events_url: string; + type: string; + site_admin: boolean; + name: string; + company: string; + blog: string; + location: string; + email: string; + hireable: boolean; + bio: string; + twitter_username: string; + public_repos: number; + public_gists: number; + followers: number; + following: number; + created_at: string; + updated_at: string; +} From 264bf205f28ffd88510741a1290bc2da51ff6d41 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 00:55:49 +0900 Subject: [PATCH 02/11] Remove old GithubUsers API --- api/src/app/controllers/github/index.ts | 18 ------------------ api/src/app/routes/api/github/index.ts | 2 -- api/src/app/services/github/index.ts | 12 ------------ 3 files changed, 32 deletions(-) diff --git a/api/src/app/controllers/github/index.ts b/api/src/app/controllers/github/index.ts index cb1baa8fb..fcaac53e4 100644 --- a/api/src/app/controllers/github/index.ts +++ b/api/src/app/controllers/github/index.ts @@ -128,21 +128,3 @@ export const listWatchersByRepository = async (req: Request, res: Response) => { return res.sendStatus(400); } }; - -export const getGithubUserByUsername = async (req: Request, res: Response) => { - try { - const githubUser = await Github.getUser({ - username: req.params.username, - }); - const { name, avatar_url, login, html_url } = githubUser; - return res.status(200).json({ - name: name, - avatar_url: avatar_url, - login: login, - html_url: html_url, - }); - } catch (e) { - console.log(e); - return res.sendStatus(400); - } -}; diff --git a/api/src/app/routes/api/github/index.ts b/api/src/app/routes/api/github/index.ts index e9d17e032..c71ca0f75 100644 --- a/api/src/app/routes/api/github/index.ts +++ b/api/src/app/routes/api/github/index.ts @@ -1,6 +1,5 @@ import express, { Router } from "express"; import { - getGithubUserByUsername, listBranchesByRepository, listCommitsByRepository, listForksByRepository, @@ -23,6 +22,5 @@ router.get("/issues/:repo", listIssuesByRepository); router.get("/count-starts/:repo", listStarsByRepository); router.get("/stargazers/:repo/:page", listStargazersByRepository); router.get("/watchers/:repo", listWatchersByRepository); -router.get("/user/:username", getGithubUserByUsername); export default router; diff --git a/api/src/app/services/github/index.ts b/api/src/app/services/github/index.ts index 2546024b3..19c6131fd 100644 --- a/api/src/app/services/github/index.ts +++ b/api/src/app/services/github/index.ts @@ -212,15 +212,3 @@ export const listWatchers = async ({ return null; } }; - -export const getUser = async ({ username }: { username: string }) => { - try { - const response = await axios.get( - `https://api.github.com/users/${username}`, - ); - return response.data; - } catch (error) { - console.log("getUser =>", error.response.data); - return null; - } -}; From 07175842ba34c88f0d5e637adec1ff1f967e65a1 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 00:56:43 +0900 Subject: [PATCH 03/11] Call v2 GithubUsers api from frontend --- web/src/apps/main/redux/actions/articles-page/index.ts | 2 +- web/src/apps/main/redux/actions/documentation-page/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/apps/main/redux/actions/articles-page/index.ts b/web/src/apps/main/redux/actions/articles-page/index.ts index eacbe9e18..5f65e019a 100644 --- a/web/src/apps/main/redux/actions/articles-page/index.ts +++ b/web/src/apps/main/redux/actions/articles-page/index.ts @@ -98,7 +98,7 @@ const fetchCurrentArticleAuthors = (): ThunkResult< const githubAuthors = ( await Promise.all( currentArticle.authors?.map((author) => { - return Axios.get(apiURL + `/github/user/${author}`); + return Axios.get(apiURL + `/v2/GithubUsers/${author}`); }) || [], ) ).map((response) => { diff --git a/web/src/apps/main/redux/actions/documentation-page/index.ts b/web/src/apps/main/redux/actions/documentation-page/index.ts index d0db6859e..01d9541f8 100644 --- a/web/src/apps/main/redux/actions/documentation-page/index.ts +++ b/web/src/apps/main/redux/actions/documentation-page/index.ts @@ -97,7 +97,7 @@ const fetchCurrentDocumentAuthors = (): ThunkResult< const githubAuthors = ( await Promise.all( currentDocument.authors?.map((author) => { - return Axios.get(apiURL + `/github/user/${author}`); + return Axios.get(apiURL + `/v2/GithubUsers/${author}`); }) || [], ) ).map((response) => { From 933c0e63b11cca410d22dac1b97cb38040e924ed Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 00:57:20 +0900 Subject: [PATCH 04/11] Use routing parameter --- api/src/github-user/controller.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/src/github-user/controller.ts b/api/src/github-user/controller.ts index f61a8bba5..73a44e120 100644 --- a/api/src/github-user/controller.ts +++ b/api/src/github-user/controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, QueryParam } from "routing-controllers"; +import { Controller, Get, Param } from "routing-controllers"; import { OpenAPI, ResponseSchema } from "routing-controllers-openapi"; import { GetUserResponseDto } from "./types"; import { GithubService } from "../github/service"; @@ -11,13 +11,13 @@ import { plainToClass } from "class-transformer"; export class GithubUserController { constructor(private readonly githubService: GithubService) {} - @Get("/") + @Get("/:username") @OpenAPI({ summary: "Return a github user with publicly available information", }) @ResponseSchema(GetUserResponseDto) public async getUserByUsername( - @QueryParam("username") username: string, + @Param("username") username: string, ): Promise { const githubUser = await this.githubService.getUser({ username, From 94a690599a028dc19c294a065c2e638849d315a6 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 02:59:02 +0900 Subject: [PATCH 05/11] Update api/src/github/service.ts Co-authored-by: Zakaria Mansouri --- api/src/github/service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/github/service.ts b/api/src/github/service.ts index c72f60620..75413d838 100644 --- a/api/src/github/service.ts +++ b/api/src/github/service.ts @@ -37,7 +37,7 @@ export class GithubService { username, }: GetUserInput): Promise => { const response = await axios.get( - `https://api.github.com/users/${username}`, + `${this.apiURL}/users/${username}`, ); return response.data; }; From 6e3d91c9da038074f1110829a26798c2cbaf80a0 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 03:25:15 +0900 Subject: [PATCH 06/11] Update GetUserResponseDto class --- api/src/github-user/controller.ts | 7 +------ api/src/github-user/types.ts | 12 ++---------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/api/src/github-user/controller.ts b/api/src/github-user/controller.ts index 73a44e120..7ec059088 100644 --- a/api/src/github-user/controller.ts +++ b/api/src/github-user/controller.ts @@ -2,9 +2,7 @@ import { Controller, Get, Param } from "routing-controllers"; import { OpenAPI, ResponseSchema } from "routing-controllers-openapi"; import { GetUserResponseDto } from "./types"; import { GithubService } from "../github/service"; -import { GithubUserDto } from "../github/dto"; import { Service } from "typedi"; -import { plainToClass } from "class-transformer"; @Service() @Controller("/GithubUsers") @@ -19,12 +17,9 @@ export class GithubUserController { public async getUserByUsername( @Param("username") username: string, ): Promise { - const githubUser = await this.githubService.getUser({ + const user = await this.githubService.getUser({ username, }); - const user = plainToClass(GithubUserDto, { - ...githubUser, - }); return { user, diff --git a/api/src/github-user/types.ts b/api/src/github-user/types.ts index 3e8395666..b2aac005a 100644 --- a/api/src/github-user/types.ts +++ b/api/src/github-user/types.ts @@ -1,17 +1,9 @@ import {} from "module"; import { GeneralResponseDto } from "../app/types"; -import { GithubUserDto } from "../github/dto"; -import { Type } from "class-transformer"; +import { GitHubUserApiResponse } from "../github/types"; import { ValidateNested } from "class-validator"; -export class GetContributorsResponseDto extends GeneralResponseDto { - @ValidateNested({ each: true }) - @Type(() => GithubUserDto) - contributors?: GithubUserDto[]; -} - export class GetUserResponseDto extends GeneralResponseDto { @ValidateNested({ each: true }) - @Type(() => GithubUserDto) - user?: GithubUserDto; + user?: GitHubUserApiResponse; } From 1eb34e192fd4b54e852d7744915f7b000cc5753a Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 10:00:07 +0900 Subject: [PATCH 07/11] Update api/src/github-user/types.ts Co-authored-by: Zakaria Mansouri --- api/src/github-user/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/github-user/types.ts b/api/src/github-user/types.ts index b2aac005a..046554600 100644 --- a/api/src/github-user/types.ts +++ b/api/src/github-user/types.ts @@ -1,4 +1,3 @@ -import {} from "module"; import { GeneralResponseDto } from "../app/types"; import { GitHubUserApiResponse } from "../github/types"; import { ValidateNested } from "class-validator"; From d7bcc00c8759ef86af44dee6326d66ed9387f4d1 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 10:29:18 +0900 Subject: [PATCH 08/11] Update api/src/github-user/types.ts Co-authored-by: Zakaria Mansouri --- api/src/github-user/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/github-user/types.ts b/api/src/github-user/types.ts index 046554600..ed01f7742 100644 --- a/api/src/github-user/types.ts +++ b/api/src/github-user/types.ts @@ -4,5 +4,5 @@ import { ValidateNested } from "class-validator"; export class GetUserResponseDto extends GeneralResponseDto { @ValidateNested({ each: true }) - user?: GitHubUserApiResponse; + user?: GithubUserDto; } From b8601fbd706b7f851096eb50b0ba7be5f2079f45 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 10:29:26 +0900 Subject: [PATCH 09/11] Update api/src/github-user/types.ts Co-authored-by: Zakaria Mansouri --- api/src/github-user/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/github-user/types.ts b/api/src/github-user/types.ts index ed01f7742..c982609fe 100644 --- a/api/src/github-user/types.ts +++ b/api/src/github-user/types.ts @@ -3,6 +3,6 @@ import { GitHubUserApiResponse } from "../github/types"; import { ValidateNested } from "class-validator"; export class GetUserResponseDto extends GeneralResponseDto { - @ValidateNested({ each: true }) + @ValidateNested() user?: GithubUserDto; } From 8f41100e357745de814edfb435abf6a87ae596e0 Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Sun, 11 Apr 2021 10:29:32 +0900 Subject: [PATCH 10/11] Update api/src/github-user/types.ts Co-authored-by: Zakaria Mansouri --- api/src/github-user/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/github-user/types.ts b/api/src/github-user/types.ts index c982609fe..380a56d52 100644 --- a/api/src/github-user/types.ts +++ b/api/src/github-user/types.ts @@ -1,5 +1,5 @@ import { GeneralResponseDto } from "../app/types"; -import { GitHubUserApiResponse } from "../github/types"; +import { GithubUserDto } from "../github/dto"; import { ValidateNested } from "class-validator"; export class GetUserResponseDto extends GeneralResponseDto { From 0efb21ccdb96ed6494f6e6d3f077f4cbaf8ea61e Mon Sep 17 00:00:00 2001 From: Woosik Kim Date: Mon, 12 Apr 2021 00:06:49 +0900 Subject: [PATCH 11/11] Update GithubUser interface --- api/src/github/dto.ts | 6 +++--- api/test/mocks.ts | 6 +++--- common/src/types/index.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/github/dto.ts b/api/src/github/dto.ts index a6aee61ce..9197ac18b 100644 --- a/api/src/github/dto.ts +++ b/api/src/github/dto.ts @@ -1,13 +1,13 @@ +import { IsNumber, IsString } from "class-validator"; import { GithubUser } from "@dzcode.io/common/dist/types"; -import { IsString } from "class-validator"; export class GithubUserDto implements GithubUser { @IsString() avatar_url!: string; // eslint-disable-line camelcase @IsString() html_url!: string; // eslint-disable-line camelcase - @IsString() - id!: string; + @IsNumber() + id!: number; @IsString() login!: string; @IsString() diff --git a/api/test/mocks.ts b/api/test/mocks.ts index e313dbf59..f3cc7b63b 100644 --- a/api/test/mocks.ts +++ b/api/test/mocks.ts @@ -3,7 +3,7 @@ import { GithubUser } from "@dzcode.io/common/dist/types"; export const githubUserMock: GithubUser = { avatar_url: "avatar_url", // eslint-disable-line camelcase html_url: "html_url", // eslint-disable-line camelcase - id: "id", + id: 1, login: "login", type: "type", }; @@ -11,7 +11,7 @@ export const githubUserMock: GithubUser = { export const githubUserMock2: GithubUser = { avatar_url: "avatar_url2", // eslint-disable-line camelcase html_url: "html_url2", // eslint-disable-line camelcase - id: "id2", + id: 2, login: "login2", type: "type2", }; @@ -19,7 +19,7 @@ export const githubUserMock2: GithubUser = { export const githubUserMock3: GithubUser = { avatar_url: "avatar_url3", // eslint-disable-line camelcase html_url: "html_url3", // eslint-disable-line camelcase - id: "id3", + id: 3, login: "login3", type: "type3", }; diff --git a/common/src/types/index.ts b/common/src/types/index.ts index b91d8b61b..b0da700b5 100644 --- a/common/src/types/index.ts +++ b/common/src/types/index.ts @@ -40,7 +40,7 @@ export type Environment = "development" | "staging" | "production"; export interface GithubUser { login: string; - id: string; + id: number; // eslint-disable-next-line camelcase avatar_url: string; // eslint-disable-next-line camelcase