묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실습으로 배우는 선착순 이벤트 시스템
안녕하세요 강사님 Redis Template에 관한 질문입니다.
사놓고 안 듣다가 이제 제대로 Redis를 학습해보려고 합니다.Redis Template를 사용하는 방식과그냥 Repository를 사용하는 방식이 있다고 들었습니다.Redis Template 말고 interface RedisRepository extends CrudRepository<>쿠폰 발급을 이렇게 정의해서 사용할 수 있나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
docker 명령어 에러 떠요
docker rm `docker ps -a- q'라고 입력했는데 unknown shorthand flag: 'a' in -a- 라고 에러 뜹니다
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
jwtstrategy error
안녕하세요 원두멘토님ㅎㅎ 이런 에러가 계속 떠서 docs와 스텍오버플로우에 검색을 해보니 Passport-jwt를 import하는 것이 아닌 passport-local을 import하는 것이라해서 했더니 다행히 실행이 됩니다.수업내용에서는 passport-jwt로만 해도 작동이 잘되는 것 같은데 왜 이런 문제가 생기는 것일까요?그리고 passport-local로 하면 실제 배포에서는 사용 못하는 것이 아닌지 질문을 남깁니다.p.s 재작년에 코캠2기 수료하고 백엔드를 많이 기다렸는데 이렇게 인프런에서 다시 인강으로 뵙게 되서 너무 반갑습니다
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
몽구스 객체값 저장하기
cheerio로 가져온값을 객체로 만든다음 밖으로 보내서 최종적으로 몽구스로 저장하고싶은데문제가 생겼던게 저상태로 보내면 [object:object] 로 나오므로 JSON.stringfy()작업으로 문자열 형태로 내보내 주었습니다. 하지만 schema부분을 object로 하여도 object가 가장 상위의 데이터 타입으로 string형태로 저장된다고 여겨졌습니다. 그래서 JSON.stringfy()로 빼내고 저장하는 부분에서 JSON.parse로 하여 다시 저장할려 했지만 다시 [object:object]로 나와서 이부분을 어떻게 해결해야할지 잘찾아봐도 모르겠어서 질문 남겼습니다.// siteInfo.js import axios from "axios"; import cheerio from "cheerio"; export class SiteInfo { siteInfo = async (prefer) => { console.log(prefer); const siteData = await axios .get(prefer) .then() .catch((err) => { console.log("서버 데이터 안받아와짐 오류 : " + err); }); const keys = []; const values = []; const $ = cheerio.load(siteData.data); $("meta").each((index, el) => { if ( $(el).attr("property") && ($(el).attr("property").includes("og:title") || $(el).attr("property").includes("og:description") || $(el).attr("property").includes("og:image")) ) { const content = $(el).attr("content"); const title = $(el).attr("property"); keys.push(title); values.push(content); } }); const arr = []; for (let i = 0; i < keys.length; i++) { arr.push({ [keys[i]]: values[i], }); } console.log("여기 테스트 : " + arr); return arr; }; } // signup.controller.js export class SignupController { siteInfoService; isValueService; saveDataService; emailService; constructor(siteInfoService, isValueService, saveDataService, emailService) { this.siteInfoService = siteInfoService; this.isValueService = isValueService; this.saveDataService = saveDataService; this.emailService = emailService; } singUp = async (req, res) => { const name = req.body.name; const email = req.body.email; const personal = req.body.personal; const prefer = req.body.prefer; const pwd = req.body.pwd; const phone = req.body.phone; console.log(req.body); const hasValue = this.isValueService.checkToken(phone); if (hasValue === false) { res.json("isAuth값이 false입니다"); } const siteInfo = await this.siteInfoService.siteInfo(prefer); const ttt = JSON.parse(siteInfo); console.log("여기 문제 발생 : " + typeof ttt); console.dir("여기 문제 발생 22222: " + ttt); const dataSave = await this.saveDataService.dataSave({ name, email, personal, prefer, pwd, phone, siteInfo, }); const isValue = this.emailService.checkMail(email); if (isValue === false) { res.send("이메일 형식이 잘못되었습니다"); } const template = this.emailService.welcomeMessage({ name, phone, prefer }); this.emailService.sendTemplateToEmail({ template, email, }); res.send("_id : " + dataSave); }; userSearch = async (req, res) => { const searchReault = await this.saveDataService.dataSearch(); console.log(searchReault); res.send(searchReault); }; } // index.js import express from "express"; import mongoose from "mongoose"; import cors from "cors"; // import { Token, User } from "./mvc/model/schema.model.js"; import { TokenController } from "./mvc/controller/token.controller.js"; import { SignupController } from "./mvc/controller/signup.controller.js"; // 사이트 정보 가져오기 import { SiteInfo } from "./mvc/controller/service/siteInfo.js"; // 핸드폰 정보 맞는지 boolean으로 import { CheckToken } from "./mvc/controller/service/token.js"; // db저장하고 리턴값 가져오기 import { UserDb } from "./mvc/controller/service/userDb.js"; // 이메일 확인하고 보내주기 import { EmailService } from "./mvc/controller/service/email.js"; // 핸드폰 문자 보내기 import { PhoneService } from "./mvc/controller/service/phone.js"; const app = express(); const corsOptions = { origin: "http://127.0.0.1:5500", }; app.use(cors(corsOptions)); const siteInfo = new SiteInfo(); const checkToken = new CheckToken(); const userDb = new UserDb(); const emailService = new EmailService(); const phoneService = new PhoneService(); app.use(express.json()); const signUpController = new SignupController( siteInfo, checkToken, userDb, emailService ); app.post("/users", signUpController.singUp); app.get("/users", signUpController.userSearch); const tokenController = new TokenController(phoneService, checkToken); app.post("/tokens/phone", tokenController.insertdata); app.patch("/tokens/phone", tokenController.checkToken); mongoose.set("debug", true); mongoose .connect("mongodb://mongodb-file:27017/dockerconnetor") .then(() => { console.log("connect success"); }) .catch(() => { console.log("fail to connect with db"); }); app.listen(3001, () => { console.log("server open"); }); // userDb.js import { User } from "../../model/schema.model.js"; export class UserDb { dataSave = async ({ name, email, personal, prefer, pwd, phone, siteInfo, }) => { const siteInforesult = JSON.parse(siteInfo); console.log("여기 확인 : " + siteInforesult); const data = new User({ name: name, email: email, personal: personal, prefer: prefer, pwd: pwd, phone: phone, siteInfo: siteInfo, }); await data.save(); const idData = await User.findOne({ phone: phone }, { _id: 1 }).exec(); return idData._id; }; dataSearch = async (name) => { console.log("start datasearch"); const result = await User.find().exec(); return result; }; } // schema.model.js import mongoose from "mongoose"; const tokenSchema = new mongoose.Schema({ phone: String, token: Number, isAuth: Boolean, }); export const Token = mongoose.model("Token", tokenSchema); const userSchema = new mongoose.Schema({ name: String, email: String, personal: String, prefer: String, pwd: String, phone: String, siteInfo: { title: String, content: String, image: String, }, }); export const User = mongoose.model("User", userSchema);
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
docker 이미지는 한개만 만들 수 있나요?
docker 빌드하고 이미지를 4시간 전에 만들었는데방금 또 빌드하고 이미지 했더니 4시간 전에 만든거라고 나왔어요.그리고 IMAGES ID도 똑같네요
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
자바스프링 병행
지금 nodejs 듣고 있는데제가 중소기업해서 취업해서 나중에 대기업 가고 싶은데일단 중소기업 취업 먼저 생각해보면 node만 공부하는게 낫나요
-
미해결그림으로 배우는 쿠버네티스(v1.30) - {{ x86-64, arm64 }}
kubernetes deploy 시 x509 오류 발생관련 문의
안녕하세요. 직접 k8s 구성을 해서 테스트 중에 오류가 발생하여 문의 드립니다. 제가 harbor 서버를 docker-compose 를 통해 직접 구축을 했고, harbor 서버에 있는 이미지를 kubernetes cluster 에서 deployment 를 이용해서 이미지를 pull 하여 배포 하려고 합니다. kubernetes cluster 에는 docker 도 같이 올라가있는데요. docker login 을 통해서 harbor 서버로 접근시에 정상적으로 login 이 되고 이미지 pull / push 가 됩니다. 다만 deployment 를 이용할때만 문제가 되는데요. 많은 기술 문서를 봤을때, sercret 키를 이용하여, deployment 파일에 imagePullSecret 항목을 통해 인증을 받아 이미지를 pull 해온다고 하는데 오류가 계속 발생합니다. 사전에 harbor 와 kubernetes 에 각각 있는 ca 인증서를 서로의 서버에 각각 배치 시켜 인증을 진행을 해야한다는데 , 몇 일째 헤매고 있어 답답한 마음에 문의 드립니다. x509: cannot validate certificate for 10.0.0.130 because it doesn't contain any IP SANsdeployment 를 통해 배포시 발생하는 에러메세지 입니다. 도움 부탁 드립니다 (__)
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
백엔드는 명령어 많이 알아야 하나요?
vscode에서 명령어 입력하고 docker 실행 명령어도 입력했는데 powershell이나 다른 프로그램에서도 명령어 많이 알아야하나요
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
NextJS 강의 순서 질문입니다.
안녕하세요. 레딧사이트 프로젝트를 진행하기 앞서 올려주신 NextJS 강의를 먼저 들으려고 합니다.강의 듣는 순서가 부록(섹션11) 먼저 듣고 섹션10(13버전)을 들으면 될까요?아니면 섹션10만 들어도 괜찮을까요?
-
미해결따라하며 배우는 도커와 CI환경 [2023.11 업데이트]
섹션9 compose up 에러
세션9 내용 따라하면서 docker compose up 커맨드를 입력했는데 다음과 같은 에러가 났습니다. 코드는 올려주신 깃헙 코드 사용하였는데 해결 방법 알 수 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
이메일 템플릿 이메일 전송
구글 앱 비밀번호 설정 떄문에 막힙니다 2단계 인증했고 앱 비밀번호 생성해서 그걸 구글 비밀번호로 바꾸고 선생님 코드를 잘 따라해서 적었는데 Error: Invalid login: 535-5.7.8 Username and Password not accepted.라고 에러 납니다혹시 방법 없을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
apollo 서버 코드 질문합니다
질문입니다type Mutation {createBoard(createBoardInput: CreateBoardInput!):String } 에서맨 마지막에 왜 createBoard는 String이 붙고type Query{fetchBoards: [MyResult]}에서 fetchBoards는 맨 마지막에 String이 안 붙나요?fetchBoards: [MyResult]:String 이렇게 될수도 있지 않나요 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ const typeDefs = `#graphqltype Query{fetchBoards: [MyResult]}type Mutation {createBoard(createBoardInput: CreateBoardInput!):String } `;const resolvers = {Query: {fetchBoards: (parent, args, context, info) => {const result = [ { number: 1, writer: "철수", title: "제목입니다", contents: "내용이에요", },{number: 2,writer: "영희", title: "제목입니다",contents: "영희이에요",},{ number: 3, writer: "훈이", title: "제목입니다",contents: "훈이이에요", },];return result;} },Mutation: { createBoard: (_, args) => { console.log(args); onsole.log("========================="); console.log(args.createBoardInput.writer);console.log(args.createBoardInput.title);console.log(args.createBoardInput.contents);return "게시물 등록에 성공하였습니다"; }, }, };
-
해결됨따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
Entity 생성 시 import 내용 자동 생성
제가 코드를 한 번에 입력하지 않고 나눠서 강의를 봐서 놓친 것일 수도 있는데..@Entity("votes")를 입력하면 제일 위쪽에 자동으로 import {Entity} from "typeorm" 등의 코드가 강의에서는 생기던데 혹시 import 코드가 자동으로 생성되지 않는 이유는 무엇일까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
학습조언 해주세요
인강 40분짜리 3개 듣고 복습해서 총 5시간을 소비했는데 잘 하고 있는 건지 궁금해요
-
미해결실습으로 배우는 선착순 이벤트 시스템
Kafka 처리량 조절 관련 문의드립니다
며칠전 수강시작했구요. 첫 완강한 인프런 유료강의가 되었네요.앞으로도 이러한 스타일 (주제중심, 적당한 총 길이)의 강의를 더 만들어주시면 감사하겠습니다.업무환경에서 다양한 기술스택을 경험하기 어려운 개발자들도 경험하면 좋을 기술스택도 좀 포함되면 더할나위 없이 좋을것 같구요. 제 경우엔 이 강의 덕분에 아주 오래전 살짝 경험해본 Redis 를 복습하게 되었고, Kafka 에 대해서도 입문하게 되었습니다.질문드립니다.이 강의에서 Kafka 이용의 장점은 처리량 조절이라고 말씀주셨습니다.처리량 조절의 구체적인 방안은구성방식, 요건등 상황에 따라 다양한 안이 있긴 하겠지만혹시 알려주실만한 방안이 있을까요? 개인적으로 찾아본것은 컨슈머 옵션중fetch.max.wait.ms 또는 fetch.max.bytes같은 옵션을 이용하면 괜찮겠다라는 생각이 들긴 했습니다.(쓰면서 생각드는건데.... 만약 두개 동시에 이용시 OR 조건으로 동작해야 될텐데.. 라는 생각이...) 경험하신 사례이든, 참고할만한 링크이든 혹시 알려주실수 있다면 감사하겠습니다.
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
null? blank? 차이
- 여러분의 질문을 고대하고 있습니다. :-)- 질문 전에 검색을 먼저 해보세요. 사람 사는 게 다 비슷하다는 것을 알게 됩니다.- 예의는 거침없이 질문하기 위한 최고의 발명품입니다.- 100개의 설명이 스크린샷 한방 보다 못할 수 있습니다.- 코드를 첨부하면 전세계 누구나 이해할 수 있는 질문이 됩니다.- 하나의 질문에는 하나의 주제를 담아야 답변도 예리해집니다.- 시행착오를 알려주시면 곧 바로 원하는 문제에 집중할 수 있습니다.- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 선생님 혹시 model 생성시 null=True와 blank=True의 차이점은 뭔가요? 둘다 값을 부여하지않아도 된다라는 식으로 이해하고 있어서요
-
미해결[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
mysql 관련 docker-compose 빌드 시 에러
강의 하나 들을 때마다 에러가 너무 많이 떠서 진도가 안나가서 미칠 지경이네요 ㅠㅠdocker-compose.yaml 파일을 아래와 같이 설정하고 docker-compose build를 하니 services.mydb.environment.0 must be a string 라는 에러가 떠서 구글링을 하니 environment: - MYSQL_DATABASE: 'dockerProject' - MYSQL_ROOT_PASSWORD: 'root'여기서 띄어쓰기를 없애보라고 하길래 아래와 같이 띄어쓰기를 없앤채로 .yaml파일을 변경하였습니다. version: '3.7' services: mybackend: build: context: . dockerfile: Dockerfile volumes: - ./src:/myfolder/src ports: - 3000:3000 env_file: - ./.env.docker mydb: # platform: linux/86_64 image: mysql:8.0.34 environment: - MYSQL_DATABASE:'dockerProject' - MYSQL_ROOT_PASSWORD:'root' ports: - 3306:3306그리고는 docker-compose build 이후 up을 실행했으나 ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...에러가 계속 발생합니다.(docker 말고 내 로컬컴퓨터에서는 mysql 연결 잘 되었음) 다른 질문자 분들 내용을 참조하여 package.json 파일의 mysql2와 typeorm의 버전을 아래와 같이 바꾸었고, .yaml 파일에서도 mysql 버전을 latest에서 8.0.34로 지정해주었습니다. { "name": "graghql", "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": { "@apollo/server": "^4.9.0", "@nestjs/apollo": "^12.0.7", "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.0.0", "@nestjs/core": "^10.0.0", "@nestjs/graphql": "^12.0.8", "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.0", "graphql": "^16.7.1", "mysql2": "3.2.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "typeorm": "^0.3.12" }, "devDependencies": { "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", "@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/parser": "^5.59.11", "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "jest": "^29.5.0", "prettier": "^2.8.8", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", "ts-loader": "^9.4.3", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", "typescript": "^5.1.3" }, "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverageFrom": [ "**/*.(t|j)s" ], "coverageDirectory": "../coverage", "testEnvironment": "node" } }그런데도 똑같이 ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...에러가 발생하여 node_modules 파일 및 dist 파일을 삭제 후 다시 yarn install을 했는데,이제는 import도 되지 않습니다....에러 때문에 진도가 나가질 않아, 중간중간에 강의를 멈춰가며 강의와 똑같이 따라가고 있는데 왜 이런 에러가 계속 발생할까요 ㅠㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
별거 아니지만 항상 궁금했던거요
객체로 나타낼 떄 따옴표 쓰는 거 하고 쌍따옴표 쓰는 거 하고 뭔 차이인가요? 그리고 따옴표 쓰면 계속 따옴표 쓰고, 쌍따옴표 쓰면 계속 쌍따옴표로 써야하나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
graphql 궁금한게 있습니다
선생님께서는type Mutation { createBoard(createBoardInput: CreateBoardInput!):String }밸류 CretaBoardInput !을 그룹으로 묶어서input CreateBoardInput{ writer:String title:String contents: String }이렇게 나타내셨는데 ,그런데 키 createBoardInput은 뭘 나타내는 건가요?혹시, 객체를 그룹으로 묶으면 키,밸류를 똑같은 이름으로 지어야 하나요>?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
graphQL 기반의 nestjs API를 생성하는 강의에 관한 질문
안녕하세요.섹션 27의 8-5 CURD API 강의를 듣다가 문득 궁금한 점이 생겨 질문드립니다.해당 강의에서는 boards.resolver.ts 파일에 fetchBoards함수와 createBoards 함수를 정의하기 위해board.entity.ts 파일, create-board.input.ts 파일, boards-service.interface.ts 파일을 아래와 같이 만드셨습니다. 아래 세 파일은 구조가 거의 동일한데, 왜 이렇게 같은 구조의 파일을 세개나 만들어서 타입스크립트 타입 정의에 사용하는 것인지 이해가 가질 않습니다.그리고 어떤 것은 class로 정의하여 타입스크릡트에 사용하고, 어떤 것은 interface로 정의하여 타입스크립트로 사용하는데 어떤 차이인지 질문 드립니다.// board.entity.ts 파일 import { Field, Int, ObjectType } from '@nestjs/graphql'; import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() @ObjectType() export class Board { @PrimaryGeneratedColumn('increment') @Field(() => Int) num: number; @Column() @Field(() => String) title: string; @Column() @Field(() => String) contents: string; @Column() @Field(() => String) writer: string; }// create-board.input.ts 파일 import { Field, InputType } from '@nestjs/graphql'; @InputType() export class CreateBoardInput { @Field(() => String) writer: string; @Field(() => String) title: string; @Field(() => String) contents: string; } // boards-service.interface.ts 파일 import { CreateBoardInput } from '../dto/create-board.input'; export interface IBoardsServiceCreate { createBoardInput: CreateBoardInput; }