월 79,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
포스트맨 실습 진행 시 undefined 오류
같은 코드를 이용해 포스트맨 호출 시, 다음 에러가 발생합니다.TypeError: Cannot read property 'moneyService' of undefined at buyProduct (file:///home/xxx/%EB%B0%94%ED%83%95%ED%99%94%EB%A9%B4/codecamp-backend-online/class/12/12-01-express-with-DI-IoC/mvc/controllers/product.controller.js:11:31) at Layer.handle [as handle_request] (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/router/layer.js:95:5) at next (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/lib/router/route.js:144:13) at Route.dispatch (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/lib/router/route.j4:3) at Layer.handle [as handle_request] (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/router/layer.js:95:5) at /home/xxx/바탕화면/codecamp-backend-online/node_modules/express/lib/router/index.js:284:15 at Function.process_params (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/lib/routedex.js:346:12) at next (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/lib/router/index.js:280:10) at jsonParser (/home/xxx/바탕화면/codecamp-backend-online/node_modules/body-parser/lib/types/json.js:7) at Layer.handle [as handle_request] (/home/xxx/바탕화면/codecamp-backend-online/node_modules/express/router/layer.js:95:5)이 때, app.post 미들웨어 함수 부분에 bind()로 엮어주어야만 정상 작동하는데 이유가 무엇일까요?코드는 아래 첨부합니다.import express from "express"; import {ProductController} from "./mvc/controllers/product.controller.js"; import {CouponController} from "./mvc/controllers/coupon.controller.js"; import {CashService} from "./mvc/controllers/services/cash.service.js"; import {ProductService} from "./mvc/controllers/services/product.service.js"; import {PointService} from "./mvc/controllers/services/point.service.js"; const app = express(); app.use(express.json()); const cashService = new CashService(); const productService = new ProductService(); const pointService = new PointService(); // 상품 API const productController = new ProductController(cashService, productService); app.post("/products/buy", productController.buyProduct) app.post("/products/refund", productController.refundProduct) // 쿠폰 구매하기 const couponController = new CouponController(pointService); app.post("/coupons/buy", couponController.buyCoupon); app.listen(3000, () => { console.log("3000번 포트에서 연결 중..."); })index.jsexport class ProductController { constructor(moneyService, productService) { // DI (IoC) this.moneyService = moneyService; this.productService = productService; } buyProduct(req, res){ // 지불 금액 검증 const hasMoney = this.moneyService.checkValue(); // 재고 검증 (재고 있으면 구매) const isSoldOut = this.productService.checkSoldOut(); // 상품 구매 코드 if (hasMoney && !isSoldOut) { res.send("상품 구매 완료"); } } refundProduct(req, res){ // 재고 검증 (재고 없으면 환불) (구매 코드와 중복) const isSoldOut = this.productService.checkSoldOut(); // 환불 코드 if (isSoldOut) res.send("환불 완료"); } }ProuductControllerexport class CouponController{ constructor(moneyService) { this.moneyService = moneyService; } buyCoupon(req, res){ const hasMoney = this.moneyService.checkValue(); // 쿠폰 구매 코드 if (hasMoney){ res.send("쿠폰 구매 완료"); } } }CouponControllerexport class ProductService{ checkSoldOut(){ console.log("판매 완료 검증."); // 재고 검증 } }ProductServiceexport class PointService{ checkValue(){ console.log("포인트 검증."); // 지불 금액 검증 } }PointServiceexport class CashService{ checkValue(){ console.log("현금 검증.") // 지불 금액 검증 } }CashService
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
Connection 부분 질문
따라하고있는데 Connection부분이 저렇게 줄이 찍 가져있고 사용되지않음으로 표시된다고 뜹니다. import부분도 그렇구요. 무엇때문에 이럴까요?
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
혹시 윈스턴으로 로거 저장하는 파트는 따로 없나요?
윈스턴이던뭐던 로그를 저장하는파트는 따로 없나요? 따라서 만들다보니 로그를 저장할 필요가 있을것같아서 시도중인데 nest는 방법을 잘 모르겠어서혹시 강의에 포함이된부분이있나해서요.
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
M:N 등록/조회 API 작성에서 Typescript 문제 질문드립니다.
안녕하세요. 제가 찾고 기다리던 내용의 강의라 매우 만족하며 수강하고 있는 수강생입니다! ㅎproducts.service.ts 파일에서 create와 update 메서드 작성할 때 typescript 에러에 대해 질문드립니다.products.service.ts 파일 create 메서드에서 productTags를 등록하는 과정에const result2 = [] 부분을 const result2: string[]로 작성하면 await productRepository.save(...) 에서 No overload matches this call이 뜨고update 메서드에서 updateProductInput에 UpdateProductInput로 타입을 지정하면 위와 마찬가지로 await productRepository.save(newProduct)에서 No overload matches this call이 뜹니다.두 경우 모두 Type 'string' is not assignable to type 'ProductTag' 문제로 product.entity.ts에서는 productTag를 아래와 같이 등록하고 @Field(() => [ProductTag]) @JoinTable() @ManyToMany(() => ProductTag, (productTags) => productTags.products) productTags: ProductTag[]; createProduct.input.ts에서는 CreateProductInput에서 productTag를 아래와 같이 등록해서 발생하는 문제라고 추측했습니다.@Field(() => [String]) productTags: string[];두 경우 모두 타입을 지정하지 않고 any로 두면 문제는 사라지긴 합니다. any로 두고 사용할 수밖에 없는 것인지 아니면 타입 지정을 해서 사용하는 방법이 있는지 궁금합니다.
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
mysql 데이터베이스 연결 안되는 문제 Unable to connect to the database
yarn start:dev 실행 하고 나면 아래와 같이 나오면서 에러가 뜨고 있어요 ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...아래 코드도 정상적으로 기입 했는데, 계속 접속 오류로 연결이 되지가 않습니다.import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo' import { Module } from '@nestjs/common' import { GraphQLModule } from '@nestjs/graphql' import { TypeOrmModule } from '@nestjs/typeorm' import { BoardsModule } from './apis/boards/boards.module' import { Board } from './apis/boards/entities/board.entity' @Module({ imports: [ BoardsModule, GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, autoSchemaFile: 'src/commons/graphql/schema.gql', }), TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'test1234', database: 'myproject03', entities: [Board], synchronize: true, logging: true, }), ], // controllers: [AppController], // providers: [AppService], }) export class AppModule {} 현재 brew 확인시 Mysql 서버도 정상적으로 켜져 있는것을 확인 할 수 있어요 디비버에서도myproject03 이라고 정확하게 만들었습니다.선생님의 강의하고 다른부분을 못 찾았는데,데이터 베이스가 연결이 안될 때는 어느부분을 더 점검 해 봐야 할지요?
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
http://localhost:3000/graphql 실행 후 query > getHello 시 오류
http://localhost:3000/graphql 실행 후 query > getHello 시 오류가 있습니다.코드는 오타 없이 동일 한데, 저는 실행시 http://localhost:3000/graphql 여기서 아래와 같은 오류가 뜨는데 어떤 상황인지 파악이 잘 되지가 않습니다.{ "errors": [ { "message": "Cannot return null for non-nullable field Query.getHello.", "locations": [ { "line": 2, "column": 3 } ], "path": [ "getHello" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "Error: Cannot return null for non-nullable field Query.getHello.", " at completeValue (/Users/back/study/20230119_nestjs/class/13-01-nestjs-with-graphql/node_modules/graphql/execution/execute.js:594:13)", " at /Users/back/study/20230119_nestjs/class/13-01-nestjs-with-graphql/node_modules/graphql/execution/execute.js:486:9", " at processTicksAndRejections (node:internal/process/task_queues:95:5)", " at async Promise.all (index 0)", " at execute (/Users/back/study/20230119_nestjs/class/13-01-nestjs-with-graphql/node_modules/apollo-server-core/src/requestPipeline.ts:501:14)", " at processGraphQLRequest (/Users/back/study/20230119_nestjs/class/13-01-nestjs-with-graphql/node_modules/apollo-server-core/src/requestPipeline.ts:407:22)", " at processHTTPRequest (/Users/back/study/20230119_nestjs/class/13-01-nestjs-with-graphql/node_modules/apollo-server-core/src/runHttpQuery.ts:436:24)" ] } } } ], "data": null } app.module.ts 에도 정상적으로 연결 해 두었습니다.import { Module } from '@nestjs/common' // import { AppController } from './app.controller'; // import { AppService } from './app.service'; import { BoardsModule } from './apis/boards/boards.module' import { GraphQLModule } from '@nestjs/graphql' import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo' @Module({ imports: [ BoardsModule, GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, autoSchemaFile: 'src/commons/graphql/schema.gql', }), ], // controllers: [AppController], // providers: [AppService], }) export class AppModule {}
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
강의에 나온 GqlAuthAccessGuard가 상속 받는 AuthGuard('myGuard')에 대해 궁금한게 있습니다.
강의자료 중 >> 회원 조회 API - 인가 << 해당 부분에서 이해가 가지 않는 게 있습니다.해당 강의 자료에서 아래와 같은 내용이 있는데요. AuthGuard와 GqlAuthAccessGuard는 부모-자식의 관계이고 getRequest 부분만 오버라이딩 한거라고 생각됩니다(요청이 rest-api가 아닌 gql이기 때문에). 그래서 AuthGuard의 기능이 GqlAuthAccessGuard에도 똑같이 있는 거라고 생각되는데 해당 자료에는 GqlAuthAccessGuard가 실행 된 뒤에 AuthGuard가 실행된다고 나와있는데요. 이 부분이 이해가 되질 않네요...
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
nest new aaa 설치 오류 문제 npx도 안돼요
nest new aaa 설치 오류 문제 npx도 안돼요몇시간째 거의 모든 방법을 다 해본거 같아요npx도 기본으로 해봤고, nest 명령어도 정상적으로 먹히는데도 불구하고 설치가 안되네요빨간색으로 뜨는 문구가Failed to execute command: yarn install --silentIn case you don't see any errors above, consider manually running the failed command yarn install to see more details on why it errored out.이렇게 2곳인데, npm / pnpm 을 해봐도 먹히지가 않아요..도저희 문제점을 찾을 수가 없었습니다 ㅠ
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
HttpStatus를 인식하지못하네용
보면서 따라하는중인데 Status를 인식하지못하네용 따로 임포트를 해줘야하는건가요?
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
graphql-upload 가 임포트 되지 않습니다 ..
{ "name": "aaa", "version": "0.0.1", "description": "", "author": "", "private": true, "license": "UNLICENSED", "scripts": { "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { "@nestjs/apollo": "^10.1.7", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", "@nestjs/graphql": "^10.1.7", "@nestjs/jwt": "^10.0.1", "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.0.0", "@nestjs/typeorm": "^9.0.1", "apollo-server-express": "^3.11.1", "bcrypt": "^5.1.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "dotenv": "^16.0.3", "graphql": "^16.6.0", "graphql-upload": "^13.0.0", "mysql2": "^2.3.3", "passport": "^0.6.0", "passport-google-oauth20": "^2.0.0", "passport-jwt": "^4.0.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0", "typeorm": "^0.3.11" }, "devDependencies": { "@nestjs/cli": "^9.0.0", "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.0.0", "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.13", "@types/graphql-upload": "^15.0.2", "@types/jest": "29.2.4", "@types/node": "18.11.18", "@types/passport-google-oauth20": "^2.0.11", "@types/passport-jwt": "^3.0.8", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "eslint": "^8.0.1", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", "jest": "29.3.1", "prettier": "^2.3.2", "source-map-support": "^0.5.20", "supertest": "^6.1.3", "ts-jest": "29.0.3", "ts-loader": "^9.2.3", "ts-node": "^10.0.0", "tsconfig-paths": "4.1.1", "typescript": "^4.7.4" }, "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverageFrom": [ "**/*.(t|j)s" ], "coverageDirectory": "../coverage", "testEnvironment": "node" } } 노드 모듈을 지우고 다시 설치했지만 .. 임포트 되지 않습니다 ..
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
건의사항
제가 잘못 본건지는 모르겠지만,Node.js API구현 중 퍼사드 패턴 47:31초에서function getToken() { const myconunt =6 if(mycount === undefined){ console.log("에러발생!!! 갯수를 제대로 입력해주세요!!!") return ~~~}좌측 인강화면을 보시면 01-04-token-count-api-facade 폴더에 들어있는index.js파일에서 function getToken() 함수에서 매개변수를 지우고, const mycount = 6 으로 대체하였습니다. 하지만, 우측 노션에 학습자료 퍼사드 패턴에서는 function getToken(count) { ~~} 라고 해서 count매개 변수가 존재합니다.count를 여전히 매개변수로 사용하고 있습니다. 즉 "노션에 있는 자료가 수정되어야 한다고 생각합니다."노션 자료 중 호출하는 부분에서 createTokenOfPhone('01012345678', 6);매개변수 6도 삭제되어야 합니다. "REST-API 실습 강의"에서 postman으로 학습시 "휴대폰 번호 전송"이 안되서 순간적으로 당황했습니다.확인하시고, 답글 달아주시면 감사하겠습니다.해당강의는 Node.js API구현 중 퍼사드 패턴 47:31초입니다. 노션은 학습 자료 / 퍼사드 패턴 입니다.
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
수업중 나온 깃허브 저장소가 없는 이유
수업중 나온 깃허브 저장소가 없는 이유가 궁금합니다.현재 스크린샷처럼 되어 있는 주소가 없어요
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
강의 툴 관련 질문입니다.
강의 툴 관련 질문입니다.선생님께서 ppt 설명 해 주실 때 사용하시는 줄긋고, 글자쓰고 이 부분이 설명하기 너무 좋아보이는데, 해당 툴 소개 받을 수 있을까요? 스터디 하면서 ppt 발표할 때 도움이 많이 될거 같아요!
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
npm에서 apollo-server 찾으면 graphql-ws 나오는데 이거 맞나요?
npm에서 apollo-server 찾으면 graphql-ws 나오는데 이거 맞나요?기존것이 디플리케이티드 되었다는 글을 보았는데,그럼 기존것을 어떻게 사용 가능한가요? npm에서 검색하면 graphql-ws 나오는데 이걸로 쓰는게 맞는지요? 사용법도 많이 달라진거 같아서 다음 진도 나가기가 어렵네요 ㅠ
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
프론트 엔드 과정보다 백엔드 과정을 먼저 수강해도 되는지요?
프론트엔드 과정을 먼저 수강하고,백엔드 과정을 수강해야 할까요?백엔드 먼저 수강해도 괜찮을까요?답변 주시면 감사하겠습니다~
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
apollo-server deprecated
@apollo/server로 업데이트 한 부분으로 강의 업데이트 해주세요 구매한지 한달도 안된 강의가 deprecated된 패키지를 쓰는건 좀 너무한거 같습니다.
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
framePage가 undefined라 진행이 되지 않습니다.
안녕하세요. puppeteer 크롤링 수업 진행 중 코드를 동일하게 했는데도 오류가 나서 질문을 남깁니다. 강의는 25분경입니다. 제 전체 코드는 아래와 같습니다.import puppeteer from "puppeteer"; async function startCrawling() { const browser = await puppeteer.launch({headless: false}); const page = await browser.newPage(); await page.setViewport({width: 720, height: 480}); await page.goto("https://finance.naver.com/item/sise.naver?code=005930"); await new Promise((page) => setTimeout(page, 1000)); // 브라우저 로딩 대기 for (let i = 0; i < page.frames().length; i++) console.log(page.frames()[i].url().includes("/item/sise_day.naver?code=005930")); const framePage = await page.frames().find((el) => {el.url().includes("/item/sise_day.naver?code=005930")}); for (let i = 3; i <= 7; i++) { const date = await framePage.$eval( `body > table.type2 > tbody > tr:nth-child(${i}) > td:nth-child(1) > span`, el => el.textContent); const price = await framePage.$eval(`body > table.type2 > tbody > tr:nth-child(${i}) > td:nth-child(2) > span`, el => el.textContent); console.log(`날짜: ${date}, 가격: ${price}`); } await browser.close(); }; startCrawling();위 코드 실행 시 framePage가 undefined로 정의되어 $eval 함수가 실행이 되지 않습니다. 그래서 혹시 frame 중에 일치하는 것이 없어서인가 싶어서 아래 코드로 콘솔에 찍어보았습니다만, true가 나오는 걸로 보아 문제가 없어야 하는것이 맞았습니다.for (let i = 0; i < page.frames().length; i++) console.log(page.frames()[i].url().includes("/item/sise_day.naver?code=005930")); /* 결과 값은 false false ...(중략)... true false false */ 왜 undefined가 나오는지 알 수 있을까요?
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
리프레시와 토큰
토큰은 만료가 되면 리프레시 토큰으로 다시 발급을 받으면 되지만리프레시가 만료가 되면 어떻게 하나요 ?
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
에러 핸들링과 db 조회 시 await을 붙이는 경우와 안붙이는 경우가 궁금합니다.
에러 핸들링의 경우 그냥 throw로 에러를 던져주기만 하는데 await을 붙여 에러를 받아야되는 이유가 궁금합니다. async checkSoldout({ productId }) { const product = await this.productRepository.findOne({ where: { id: productId }, }); if (product.isSoldout) throw new UnprocessableEntityException('이미 판매가 완료된 상품입니다.'); }@Mutation(() => Product) async updateProduct( @Args('productId') productId: string, @Args('updateProductInput') updateProductInput: UpdateProductInput, ) { // 여기서 에러를 받았을 때 await을 붙여야 정상동작을 하는데 이유가 궁금하네요. await this.productService.checkSoldout({ productId }); return this.productService.update({ productId, updateProductInput }); } 제가 실험삼아 db를 업데이트 할 때 await을 빼고 로직을 수행해 봤는데 정상적으로 동작하는 듯 보입니다. 이게 왜 동작하는 건지 모르겠네요...// async await을 모두 제거했습니다. update({ productId, updateProductInput }) { const newProduct = { id: productId, ...updateProductInput, }; return this.productRepository.save(newProduct); }@Mutation(() => Product) async updateProduct( @Args('productId') productId: string, @Args('updateProductInput') updateProductInput: UpdateProductInput, ) { await this.productService.checkSoldout({ productId }); // 리턴을 받을 때도 기다리지 않고 바로 진행했습니다. return this.productService.update({ productId, updateProductInput }); }이 때 서버를 돌리고 쿼리를 실행해보면 정상적으로 수행이 되는데(출력해보면 pending 상태입니다...) 이해가 잘 안되네요..
- 해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
Docker compose image 옵션
안녕하세요. Docker-compose services 옵션 중에 image에 대해 궁금한 점이 있습니다.강의에서 mongoDB dockerfile에는 'FROM mongo:5' 이렇게만 작성했는데 이걸 image옵션으로 허브에서 가져오면 dockerfile없이 docker-compose를 할 수 있는건지 궁금합니다.image 옵션과 build옵션을 둘 중 하나만 사용해야하는건지image옵션을 쓰면 dockerfile이 없어도 되는건지(dockerfile이 있을 때만 build옵션을 사용하는건지)dockerfile없이 docker-compose를 사용할 수 있는지강의 덕에 쉽게 도커에 입문할 수 있게 되었어요. 감사합니다.