묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결탄탄한 백엔드 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. 자꾸 질문드려 죄송합니다ㅠ)
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
소켓 연결관련 질문입니다.
강의에서 socket.id는 계속 유지되다가 연결이 끊기거나 새로고침되면 바뀐다고 나오는데요 즉, 새로고침하면 소켓연결이 끊긴다는 뜻인데 이걸 막을 방법이 있나요? 예를 들어서 제가 웹 상에서 멀티플레이가 가능한 카드게임을 구현한다고 하면 게임 플레이 도중 사용자가 실수로 새로고침을 누르면 끊겨버릴텐데 이런 상황에서는 어떤식으로 처리를 하나요? 또 질문이 하나 있는데 강의와는 조금 벗어난 질문이긴한데.. 소켓연결에 더해서 redis까지 이용해서 만들어보려고 하는데 구글에 nestjs redis 이렇게 검색하면 나오는 공식문서가 Microservice 어쩌고 하면서 redis랑 같이 나오더라구요. 제가 구현하고 싶은 기능은 웹상에서 방을 만들고, 사용자들이 해당 방에 들어가면 사용자들의 정보를 redis에 담고 redis pub/sub과 소켓을 이용하여 같은 방안에 사용자들끼리 통신하는 그런걸 만들어보고 싶은데 이 경우에 공식문서에 나와있는 Microservice.. 를 쓰면 되는게 맞는건지 잘 모르겠어서 질문드립니다.
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
async await 질문 있습니다.
강의 잘 보고 있습니다! 보다가 궁금한 점이 생겼는 데 async 함수에서 return 할 때 await 을 안붙이시던데 이유가 있을까요?
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
1분 18초 자바스크립트 어떤건 힙에 저장되고 어떤건 스택에 저장되고...
1분 18초 자바스크립트 어떤건 힙에 저장되고 어떤건 스택에 저장되고... 에 대해 말씀하셨는데, 혹시 그런거에 관해 좀 더 알기 위해 공부해보고 싶은데, 공부 자료 추천해주실 수 있나요? (신기... 제로초님은 어떤 자료를 통해 그러한 내용들을 알게되셨나요?
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
예전부터 궁금했던 보안관련 질문있습니다.
안녕하세요. 예전부터 궁금사항이 있었는데, 실제로 결제 관련된 한 서비스를 운영하시는 걸로 알고 있습니다. 실제 은행과 같은 정말 보안적으로 최고로 중요한 서비스는 아니더라고, 실제 돈이 오가는 결제 서비스이기에 보안관련 예민하게 작용을 할텐데, 일반적인 passport 나 쿠키 관리, 또는 APP과 통신을 하면서 JWT 토큰을 오가는 정도로는 보안을 강화하기는 힘들 것 같은데, 실제 결제 서비스가 운영되는 정도의 프로젝트에서는 어느정도까지, 어떻게 보안을 강화하여 사용하고 있는지가 정말 너무 궁금했습니다. 예전부터.. 디테일하게 과정까지 말씀해주시면 좋겠지만, 이정도까지 처리하고있다 정도라도 말씀해주시면 너무 감사할것 같습니다 ㅠㅠ
-
해결됨탄탄한 백엔드 NestJS, 기초부터 심화까지
프론트 코드는 어디서 받나요?
https://github.com/amamov/teaching-nestjs-a-to-z 에 있는 frontend 디렉토리가 프론트코드인가요?
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
Filter도 결국 middleware에서 처리할 수 있을거 같은데 나누는 이유가 있을까요?
Filter도 결국 middleware에서 처리할 수 있을거 같은데 나누는 이유가 있을까요?