묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
파일을 클릭하면 제일 1번라인 import에 빨간줄 문의드립니다
안녕하세요 강사님 궁금하게 생겨 문의 드립니다. 다음 사진처럼 항상 파일을 클릭하면 상단 import줄이 저렇게 변하는데요 파일을 다시 닫으면 빨간줄이 사라집니다. 깃허브에 있는 tsconfig.json과 .eslintrc.js는 그대로 복붙했습니다. 제가놓친게있을까요?
-
해결됨탄탄한 백엔드 NestJS, 기초부터 심화까지
cats.module.ts에서 MongooseModule.forFeature 질문 드립니다
안녕하세요 강사님 cats.module.ts 파일에서 import: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }]),이부분에서 빨갛게 해논부분에 왜 Cat.name , name이 붙어있는 이유가 뭔지 알고싶습니다. 저기서 name에 할당한 값으로 Service에서 생성자 주입 받을때? Cat.name 으로 @InjectModel(Cat.name) 하는걸로 보이는데 왜 ".name" 이 붙은건가요?..
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
혹시 NestJS GraphQL - Apollo 강의도 가능할가요?
강의 정말 너무 유익하게 잘 들었습니다! 혹시 GraphQL 강의도 가능할까요?새롭게 내셔도 너무 좋을 것 같아요~
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
mvc패턴을 사용한 예제를 볼 수 있는곳이 있나요?
공식문서에서는 SSR방식을 사용한다고 하셨는데, CSR을 사용하는 방식과, MVC패턴을 사용한, 사용하지 않은 코드를 보면서 차이를 보고 싶습니다 예제 사이트와 코드는 어디서 찾을 수 있나요?
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
소셜 로그인 질문 (passport-apple)
저는 passport-jwt를 사용하여 로그인을 구현하였는데, 소셜 로그인을 위해 passport-apple 를 사용하여 유저 정보를 받아오려고하는데 막혔습니다. https://github.com/ananay/passport-apple/issues/30 nest.js에서 passport-apple사용시 Strategy 클래스의 validate함수에 인자가 제대로 들어오지않는 이슈가 있는것같습니다. 제가 유저정보를 받아온후 그것을 db에 저장후 jwt를 발행하여 다음요청부터는 애플을 거치지않고 제 서버로 jwt를 보내면 제가 유저정보 주는방식으로 구현하려고하는데, 유저 정보를 어떻게 받아와야하는지 모르겠습니다. 구글링해보니 idToken을 decode하면 유저정보가 들어있다고하는데, import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { PassportStrategy } from '@nestjs/passport'; import { DecodedIdToken, Strategy, VerifyCallback } from 'passport-apple'; @Injectable() export class AppleStrategy extends PassportStrategy(Strategy, 'apple') { constructor(private jwtService: JwtService) { super({ clientID: process.env.APPLE_CLIENT_ID, teamID: process.env.APPLE_TEAM_ID, callbackURL: process.env.APPLE_CALLBACK_URL, keyID: process.env.APPLE_KEY_ID, privateKeyString: process.env.APPLE_KEY.replace(/\\n/g, '\n'), passReqToCallback: false, }); } async validate( accessToken: string, idToken: string, profile: any, done: VerifyCallback, ) { const decodedIdToken: DecodedIdToken = this.jwtService.verify(idToken); console.log(decodedIdToken); const user = { provider: 'apple', snsId: decodedIdToken.sub, password: decodedIdToken.sub, }; console.log(user); done(null, user); } } 이렇게 코드를 짜니 [Nest] 31 - 02/06/2022, 8:41:18 AM ERROR [ExceptionsHandler] jwt malformed JsonWebTokenError: jwt malformed at Object.module.exports [as verify] (/usr/src/app/node_modules/jsonwebtoken/verify.js:63:17) at JwtService.verify (/usr/src/app/node_modules/@nestjs/jwt/dist/jwt.service.js:37:20) at AppleStrategy.validate (/usr/src/app/src/auth/strategies/apple.strategy.ts:25:60) at AppleStrategy.<anonymous> (/usr/src/app/node_modules/@nestjs/passport/dist/passport/passport.strategy.js:20:55) at Generator.next (<anonymous>) at /usr/src/app/node_modules/@nestjs/passport/dist/passport/passport.strategy.js:8:71 at new Promise (<anonymous>) at __awaiter (/usr/src/app/node_modules/@nestjs/passport/dist/passport/passport.strategy.js:4:12) at AppleStrategy.callback [as _verify] (/usr/src/app/node_modules/@nestjs/passport/dist/passport/passport.strategy.js:17:45) at /usr/src/app/node_modules/passport-oauth2/lib/strategy.js:205:24 이러한 에러가 뜹니다. idToken을 어떻게 해독해야하는지 알수있을까요..? 혹시 실무에서 애플로그인 서비스를 구현해보셨다면 이방법말고 다른방법이라도 있다면 알려주시면 감사하겠습니다!
-
해결됨탄탄한 백엔드 NestJS, 기초부터 심화까지
Comments Module에서 DB import를 하지않아도 상관없나요?
@Module({ imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])], controllers: [CatsController], providers: [CatsService], }) Cat Module 에서는 위와 같이 import를 해줬는데 Comment Module에서는 import를 하나 안 하나 정상적으로 동작합니다 왜 Comment Module에서는 안 하신건가요?
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
swagger용 데코레이터 작성 방법
swagger를 위한 정보를 decorator를 통해 추가하다보면 ApiOperation 뿐만 아니라 ApiBody, ApiResponse 등 다양한 decorator가 추가되고 이에 대한 인자를 객체로 만들어서 넣어주는 과정에서 코드가 굉장히 지저분해지고, decorator에 들어가는 객체들에 대한 정보 관리가 어려워 지는 거 같습니다 . 이런 경우에 커스텀 데코레이터를 만들어서 하나로 합쳐서 사용하고 싶은데 이러한 커스텀 테코레이터에 대해서 간단하게 작성방법을 강의영상으로 추가해주실 수 있을 지 문의 드립니다.
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
안녕하세요 강사님 실행할때 오류가 발생해서 질문드립니다.
Error: Cannot find module 'app.model' Require stack: - D:\Study\Inflearn\NestJS\Express\letsStart\dist\app.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.Module._load (node:internal/modules/cjs/loader:778:27) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) at Object.<anonymous> (D:\Study\Inflearn\NestJS\Express\letsStart\dist\app.js:4:19) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) { code: 'MODULE_NOT_FOUND', requireStack: [ 'D:\\Study\\Inflearn\\NestJS\\Express\\letsStart\\dist\\app.js' ] } npm run start:dev 했을때 이와같은 오류가 발생하고 postman도 마찬가지로 localhost:8000으로 get 검색시 찾지 못하는데 어느 부분에서 잘못됬는지를 모르겠습니다. 코드는 오타 없이 강사님이 작성한것과 동일합니다.
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
CQRS 패턴과 gql 강의 요청
혹시 NESTJS의 CQRS 패턴과 graphql(with dataloader and federation) 강의도 해주실 수 있나요??
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
하나의 게시물에 여러 개의 태그(카테고리)를 조회하고 싶습니다
현재 nestjs로 Stackoverflow와 유사한 교내 웹 개발 커뮤니티를 개발하는 학생입니다. 전체 질문글을 조회하는 기능을 개발하다가 한 가지 궁금점이 발생하여 질문하게 되었는데요! 주제넘게 설명을 드리자면 '전체 질문글 조회'는 velog나 stackoverflow와 같은 사이트의 루트페이지를 생각해주시면 될 것같습니다. 모든 질문글을 조회하는 과정에서 하나의 질문글에 여러 개의 카테고리가 저장되어 있을 경우 해당 질문글에 연관 돼있는 카테고리가 배열에 담겨 반환되는 것이 아닌 같은 질문글에 다른 카테고리를 가진 똑같은 질문글들이 조회됩니다. 즉, 다시 말해 질문글은 같지만 카테고리만 다른 데이터가 카테고리의 갯수만큼 조회됩니다..!! 이건 저희 프로젝트 erd입니다. 다음은 같이 querybuilder를 이용하여 left join을 한 코드입니다. 아래 사진은 위 querybuilder를 통해 도출된 결과입니다 위의 내용은 전체 조회에서 필요한 하나의 질문글에 대한 정보들은 조회한 사진입니다. 제가 원하는 출력 결과는 위의 카테고리가 따로 조회되는 것이 아닌 ```typescript TextRow { username: '송유현', '댓글내용': '댓글1', '제목': 'typeorm이 뭐에요', '내용': '제곧내', '좋아요': 3, '생성시간': 2021-12-21T15:00:00.000Z, '태그': [ [ '킥킥'] , ['typeorm'] ] }, ``` 의 형태로 출력하고 싶습니다..
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
제로초님 nestjs vscode에서 디버깅하는 것 좀 알려주시면 감사합니다.
안녕하세요 제로초님. 강의 잘 봤습니다. 그런데 제가 vscode에서 nestjs 프로젝트를 하면서 브레이킹 포인트로 디버깅을 하고 싶은데 브레이킹 포인트가 안 먹혀서 질문드립니다. 인터넷에서 보고 launch.json 파일도 만들어서 해봤는데 계속 타입스크립트로 디버깅이 안되더라고요. 방법을 알려주시면 감사하겠습니다.
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
안녕하세요 :) 스웨거 관련 질문이 있습니다!
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 :) 강의해 주신 내용을 기반으로 소켓을 이용한 실 서비스를 구현해 보고 있는데요. 다름이 아니라 소켓 부하 테스트를 해보니 처리 못하는 요청 건수가 많아, NodeJS에서 기본적으로 제공해 주는 프로파일링을 해보았고, 그 결과 스웨거 프레임워크가 상당히 많은 CPU 리소스를 잡고 있는 것을 확인했습니다. (물론 사용 중인 AWS EC2의 사양이 낮기도 합니다.) 강의 중에 스웨거 다소 무겁다고 하셨었는데.. 실제로 체감해 보니, 스웨거가 왜 이렇게 많은 CPU를 차지하는 지, 그리고 강사님께서는 왜 무겁다고 하셨는 지 근본적인 원인이 궁금해졌습니다! 스웨거 단점을 인터넷에 찾아보니 무겁다는 측면에 대해서는 크게 언급이 없어 여기에 질문을 남깁니다! 최대한 기술적인 측면에서 답변을 해주시면 정말 감사하겠습니다!
-
해결됨탄탄한 백엔드 NestJS, 기초부터 심화까지
TypeORM 트랜잭션 질문드립니다.
안녕하세요 윤상석 강사님. TypeORM의 트랜잭션 관련으로 질문이 있습니다.TypeORM에서 트랜잭션을 다루는 방법은 이전 질문글에 답변해주셨듯이 크게 3가지인 것으로 알고 있습니다.1. QueryRunner2. getConnection, getManager3. @Transactional개인적으로는 @Transactional() 데코레이터를 사용하는것이 편리하여 사용하고 있었는데요.NestJS 공식문서에서 데코레이터를 이용하는 것을 권장하지 않고 있고,구글링을 해보아도 유닛 테스트에 어려움이 있어 권장하지 않는 분들이 많은 것을 알게되었습니다.여기서 첫 번째 질문이 있습니다.Q1. "유닛 테스트에 어려움이 있다"는 이야기가 구체적으로 무슨 의미인지 궁금합니다. 모킹이 어렵다. 내 마음대로 제어가 불가능하다 등의 이야기가 이해는 가는데 와닿지는 않아서 질문드립니다.----QueryRunner 방식을 이용하게 되면 try-catch-finally 코드가 강제가 되는 것 같아보입니다.여기서 두 번째 질문이 있습니다.Q2. 모든 에러를 감지하는 Filter를 적용해두었다면 QueryRunner를 사용하는 try-catch-finally 구문에서 에러 처리를 해버려 필터가 작동하지 않을 것 같은데 맞을까요?맞다면, 만약 Filter에서 요청이 실패하였을 때의 로깅기능이 있다고 가정한다면 로깅기능이 작동하지 않을 것 같습니다.그렇다면 catch 문에서 따로 Filter에서 구현한 로깅을 다시 구현해주어야 할까요?----트랜잭션 처리를 도와주는 typeorm-transactional-cls-hooked 패키지를 발견하였습니다.여기서 마지막 세 번째 질문이 있습니다.Q3. 해당 패키지는 유닛 테스를 할 때 트랜잭션 기능이 작동하지 않도록 모킹기능도 제공해주는 것 같습니다. QuerryRunner 보다 안 좋은점이 있다면 어떤 점이 있을까요?----질문이 너무 많은 것 같아 죄송합니다.좋은 강의와 답변해주셔서 항상 감사합니다.
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
useFactory 사용시 resource 파일 분리 후 di 방법
먼저 너무 좋은 ADMIN 대시보드 라이브러리를 알려주셔서 감사합니다. 해당 라이브러리로 몇가지 테스트해보는 중인데 adminJsOptions가 너무 길어져 resources를 별도의 파일로 분리하려 하고 있습니다. 하다보니 이미 factory로 blogModel을 inject하고 있는데 resources를 별도의 파일로 분리하려고 보니 blogModel을 분리한 파일에서 어떻게 가져와야할지 막막하더라구요. adminjs뿐아니라 다른 모듈을 사용할때도 useFactory를 통해 di를 해주는경우가 많은데 이럴때는 분리된 파일에는 어떻게 의존성을 주입해줘야 할까요??? 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 import * as AdminJSMongoose from '@adminjs/mongoose'; import { AdminModule as AdminBroModule } from '@adminjs/nestjs'; import { Module } from '@nestjs/common'; import { getModelToken } from '@nestjs/mongoose'; import AdminJS from 'adminjs'; import { Model } from 'mongoose'; import { UsersModule } from 'src/users/users.module'; import { User } from 'src/users/users.schema'; import { after, before } from './hooks/users.hooks'; AdminJS.registerAdapter(AdminJSMongoose); @Module({ imports: [ AdminBroModule.createAdminAsync({ imports: [UsersModule], inject: [getModelToken(User.name)], useFactory: (usersModel: Model<User>) => ({ adminJsOptions: { rootPath: '/admin', resources: [ { resource: usersModel, options: { navigation: { name: null, icon: '', }, properties: { email: { isTitle: false, position: 1, }, name: { isTitle: true, }, _id: { isVisible: { list: false }, }, password: { isVisible: false, }, }, actions: { edit: { isAccessible: isAdmin }, delete: { isAccessible: isAdmin }, new: { isAccessible: isAdmin }, show: { isAccessible: isAdmin, }, list: { isAccessible: isAdmin }, custom_delete: { actionType: 'record', icon: 'TrashCan', guard: 'doYouReallyWantToDoThis', variant: 'danger', before: before, after: after, handler: async (request, response, context) => { const user = context.record; await usersModel.findOne({_id: request.params.id}); console.log('custom handler!!!'); return { record: user.toJSON(context.currentAdmin), }; } }, }, }, }, ], }, auth: { authenticate: async (email, password) => { const user = await usersModel.findOne({ email: email }); if (user) { const matched = user.password === password; if (matched && user.role === 'ADMIN') { return user.readOnlyData; } } return null; }, cookieName: 'cookie-test', cookiePassword: 'test', }, }), }), ], }) export class AdminModule {} const isAdmin = ({ currentAdmin }) => currentAdmin && currentAdmin.role === 'ADMIN'; resource 코드 분리 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 import * as AdminJSMongoose from '@adminjs/mongoose'; import { AdminModule as AdminBroModule } from '@adminjs/nestjs'; import { Module } from '@nestjs/common'; import { getModelToken } from '@nestjs/mongoose'; import AdminJS from 'adminjs'; import { Model } from 'mongoose'; import { UsersModule } from 'src/users/users.module'; import { User } from 'src/users/users.schema'; import { after, before } from './hooks/users.hooks'; import { userResource } from './resources/users.resource'; AdminJS.registerAdapter(AdminJSMongoose); @Module({ imports: [ AdminBroModule.createAdminAsync({ imports: [UsersModule], inject: [getModelToken(User.name)], useFactory: (usersModel: Model<User>) => ({ adminJsOptions: { rootPath: '/admin', resources: [ userResource ], }, auth: { authenticate: async (email, password) => { const user = await usersModel.findOne({ email: email }); if (user) { const matched = user.password === password; if (matched && user.role === 'ADMIN') { return user.readOnlyData; } } return null; }, cookieName: 'cookie-test', cookiePassword: 'test', }, }), }), ], }) export class AdminModule {} const isAdmin = ({ currentAdmin }) => currentAdmin && currentAdmin.role === 'ADMIN'; 함수로 만들어 파라미터로 넘겨주는 방법밖에 없을까요???
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
next()가 없는 (불필요한) 경우에도, middleware 함수라고 볼 수 있나요??
안녕하세요~ 좋은 강의 넘 잘 듣고 있습니다~ 감사합니다 :) 이 에러 핸들링을 하는 함수를 middleware라고 언급해주셨는데, 저는 조금 헷갈려서 질문 드립니다! app.use((req: express.Request, res: express.Response, next: express.NextFunction) => { console.log('this is error middleware'); res.send({ error: '404 not found error' }); }); 미들웨어는 하려는 일의 중간에서, 개발자가 원하는 무언가를 할 수 있도록 하는 것을 말하는거니까 express 에서는 next() 가 있는 경우를 middleware 로 본다 는 것으로 이해했습니다. 그런데 위 코드는 다음으로 넘기는 것 없이 바로 404를 반환해서, next가 꼭 필요하지 않은 것 같은데... 이 경우에도 이 함수를 middleware 함수라고 볼 수 있나요~?
-
미해결따라하며 배우는 NestJS
Dependency Injection에 관해
안녕하세요 선생님, 항상 좋은 강의 감사드립니다. DI 관련해서 궁금한 점이 생겨 질문드립니다. Controller에서 Service 클래스를 DI 받을 때는 별도의 데코레이션 없이 DI를 받았는데, service 계층에서 repository를 DI 받을 때는 왜 @InjectRepository가 필요할까요? 개인적으로 생각해보기로는, 우리가 직접 만든 Service 클래스는 Nest IOC container에서 관리되지만, Repository 클래스는 TypeORM 모듈에 의해 DI가 관리되기 때문일 수도 있겠다는 생각을 해봤습니다.
-
미해결따라하며 배우는 NestJS
안녕하세요 강의자료 질문드립니다!
안녕하세요! 항상 좋은 강의 올려주셔서 도움많이 받고 있는 1인입니다.다름이아니라 수업자료를 다운받으면 DS_STORE 파일로 밖에 안보이는데 윈도우에서는 어떻게 확인하는 방법이 있나요?
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
글과 댓글 매칭 부분이 되지 않습니다. populate
cat 대신하여 dog로 저는 따라 작성하였습니다. docs 페이지에 정의 되어 있습니다. postman으로 get 방식으로 dog/all로 호출 하였을때 comments schema가 등록이 안되었다고 되어 있는데 git 코드와 비교 해보면 다른점이 없어보여 질문드립니다. 출력해주는 에러에서는 [Nest] 26612 - 2021. 10. 15. 오후 3:33:29 ERROR [ExceptionsHandler] Schema hasn't been registered for model "comments". Use mongoose.model(name, schema) export class DogRepository { constructor(@InjectModel(Dog.name) private readonly dogModel: Model<Dog>) {} async findAll() { console.log('findAll function'); const CommentsModel = mongoose.model('comments', CommentsSchema); console.log(CommentsModel); const result = await this.dogModel .find() .populate('comments', CommentsModel); console.log(result); return result; } 와 같이 추가되었습니다. 다만 populate이부분을 사용 안하면 정상 작동하나 두 collection의 join은 되지 않습니다. 혹시 에러 원인을 파악할수 있는 부분이나 제가 check해야될 부분이 있을까요?? 다른기능은 정상 작용 중입니다.
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
http-exception.filter.ts 파일 내용 중 질문이 있습니다.
const error = exception.getResponse() as | string | { error: string; statusCode: number; message: string | string[] }; 강의 중에 http-exception.filter.ts 파일에서 error 변수를 위와 같이 할당을 하는데 as | string 뒤에 있는 타입을 { error: string, statusCode: number; message: string | string[] };로 받는데 객체의 속성들을 특별하게 넣어준 이유가 있나요? 단순히 { error: string }로만 처리해도 다른 속성 값들이 자동으로 들어오기 때문에 출력할 때는 문제가 없는 것 같은데 정확한 타입을 제공하기 위해서 라던가 등 특별한 이유가 있는지 궁금합니다.
-
해결됨탄탄한 백엔드 NestJS, 기초부터 심화까지
catsController에서 files가 undefined
업로드하면 dist에 파일은 저장이 되고 확인도 되는데, catsController에서 console.log(files)을 찍어봐도 undefined가 나와서 files[0]의 type error가 납니다. 아무리 봐도 제대로 한 것같은데 안들어와서 질문 드려요 참고로 FilesInterceptor의 인자 중 maxCount가 제 프로젝트의 버전에는 없어서 인자를 두개만 넣었습니다. 코드 올렸으니 안 바쁘실 때 한번만 봐주시길 바랍니다 https://github.com/GroundP/CatsCommunity (ps. 자꾸 질문드려 죄송합니다ㅠ)