묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
nest 실행 (npm run start:dev)이 너무 오래 걸려요
typescript 기초 강의에서 nest를 처음 실행했는데 실행 시 너무 오래 걸립니다..(약 20~30분 정도) windows os에서 실행 햇는데 이유가 있을까요?현재 컴퓨터 사양은 Memory 32G 에 RAM 16 Core 입니다.매번 이렇게 시간이 걸리면 현실적으로 test가 불가능해서 방법을 구하고자 합니다. +추가yarn으로 실행해봐도 비슷하네요..Windows OS에서 WSL 통해서 Ubuntu 환경에서 실행하고 있습니다.
-
해결됨비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
일정시간마다 자동으로 데이터를 생성하는 코드를 짜려고 합니다.
외부 api 에서 ajax를 통해 데이터를 받아오고, 받아온 데이터를 카피해서 mysql 에 삽입하고자 합니다.일정시간마다 반복하는 것은 setInterval 을 활용하면 되는것까지는 구글링을 통해 알아냈는데본 강의에서는 데이터 생성을 postman 을 사용해 수동으로 데이터를 입력하고 전송하셔서 코드 상으로는 어떻게 구현해야 할지 궁금해서 여쭤봅니다! 1줄요약!postman을 통해 했던 데이터 삽입을 코드로 하는 방법이 궁금합니다!
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
유튜브 썸네일 따는 과정에서 오류가 생겨요 숏츠는 다른 방법이 있나요?
유튜브 숏츠의 썸네일을 사용하려고 합니다인포윈도우 가공하기 단계에서 똑같이 하는데도 섬네일이 오류표시가 나요ㅜㅜ숏츠는 방법이 다른건가요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
API-Gateway2 섹션 Apollo 서버 구동 에러
Auth와 Resource App 시작 시 아래 사진과 같은 에러가 발생합니다. 강의와 노션에 있는 코드를 그대로 작성했다고 생각하여 패키지 버전 문제로 추정됩니다.현재 제가 사용중인 패키지입니다.강의 중 사용중인 패키지 버전을 공유받고 싶습니다. 해당 오류에 대한 구글링에 실패해서 추가적으로 혹시 알고계신 레퍼런스 있으시면 알려주시면 감사드리겠습니다.
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
Contact 설정 관련해서 질문이 있어요
제가 html, css 등 까지 수강하고 배포 등 다음 과정으로 넘어가려고 하는데 Contact를 활용하는 강의를 못 본거 같아서요 혹시 제가 놓친 부분이 있을까요? 감사합니다..!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
암호화/인증 & 인가 과제 중 질문
updateUserPwd 구현 중에, 파라미터로 업데이트할 패스워드를 받도록 했습니다. 이 때, API 호출 시, 해당 파라미터의 최소 길이를 8 이상으로 하고 싶은데 따로 방법이 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
액세스토큰을 변수로 저장하면 생기는 문제점
안녕하세요. 강의중에 액세스토큰을 변수로 req.header에 저장하면 아래와 같이 3가지 문제점이 있다는 것을 구글링을 통해서 확인했습니다.1.보안: 액세스토큰을 req.header에 변수로서의 토큰은 공격자에 의해 가로채기에 취약합니다.2.확장성: 애플리케이션에 많은 수의 요청이 있는 경우 req.header의 변수는 크기가 커지고 성능 문제가 발생할 수 있습니다.3.지속성: req.header에 액세스 토큰을 저장하는 것은 영구적이지 않습니다. 사용자가 페이지를 새로 고치거나 브라우저를 닫으면 액세스 토큰이 손실됩니다. 이로 인해 사용자가 보호된 리소스에 액세스하기 위해 다시 로그인해야 할 수 있습니다. 질문1)3번 지속성문제의 경우, 브라우저를 새로고침하게 되면, 액세스 토큰이 사라지게 되니 오히려 보안이 좋다고 생각해야 할까요? accessToken이 수업에서는 10분으 로 만료기간을 설정했는데, restoreAccessToken API가 있기 때문에 acessToken을 req.header에 변수로 저장해도 문제가 되지 않을까요? 질문2)액세스토큰 만료시간을 10분 ~30분 으로 짧게 잡으신 이유가 1번 문제점 보안의 이유라고 생각하면 될까요? 질문3)선생님, 좋은 강의 해주셔서 진심으로 감사합니다. 저는 선생님의 백엔드와 프론트 강의를 수강후 실제 웹 서비스를 런칭하기위해서 수업을 듣고 있습니다. 현재는 백엔드 강의를 수강중입니다.실제 웹 서비스런칭시 accessToken을 req.header에 변수로서 저장하고, refreshToken은 쿠키에 저장하는 게 올바른 방법인가요?refreshToken을 수업에서 가르쳐주신 대로 secure : true, httponly: true와 같이 배포환경으로 바꿔서 배포하게 된다면 보안상 안전할까요? 질문4)구글링을 해보니, 리프레시 토큰을 Redis에 저장하고, 액세스토큰은 쿠키에 저장하는 방법도 있는 것을 확인했습니다. 액세스토큰의 만료기간을 10분으로 잡고, 리프레시토큰의 만료기간을 2주로 잡을 경우, restoreRefreshToken API 때문에 Redis DB에 자주 접속하게 되어서 DB 사용료가 많이 청구 되지는 않을까요? 서버를 stateless 상태로 웹 서비스를 런칭하기 위해서는 액세스토큰과 리프레시 토큰을 어떻게 저장해야 할까요? 가장 안전한 방법이라고 할 수 있을까요? 감사합니다.
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
User 의 List<Post> posts 컬렉션 조회시
안녕하세요. JPA 로 Post 를 등록하고 User 의 List<Post> posts 컬렉션 정보를 조회할때 질문드립니다.post 등록시 User 의 List<Post> posts 컬렉션에 따로 post 를 넣지 않았는데 조회할 경우에 post 정보가 나오게되는 이유가 궁금합니다.... post가 User 컬렉션에 자동적으로 저장되는 것인가요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
GqlExecutionContext가 없다고 나옵니다.
import { GqlExecutionContext } from '@nestjs/graphql';@nestjs/graphql 모둘에 내보낸 맴버 GqlExecutionContext가 없다고 에러가 뜹니다
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
JWT 토큰이 어디 저장되어 있는 건가요?
인증을 하면 JWT 액세스 토큰을 전달 받고, fetchUser의 header에 전달 받은 토큰을 넘겨 인가를 받는다는 것을 알았습니다.이 때, JWT 토큰에 대해 서버가 알고 있어야 하는데 이것이 어디에 저장되어 있는 건가요?
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
@Size(min, max) 검증 관련 질문
안녕하세요.User 테이블에 데이터를 삽입하다 검증 애노테이션이 적용이 안되서 질문드립니다. 동일한 질문이 있어서 Javax.validation 의존성 삭제하고 springboot.starter validation 을 적용했지만 계속 검증이 안되는 상황입니다.@Size(min=2, max=4)private String name;이름 필드에 제한을 두었는데 max 테스트는 에러를 내보내지만 min 을 테스트했을때 한글자 문자를 넣었을 때 왜 에러가 발생되지 않는지 궁금합니다..
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
강의별 전체 코드 git으로 받아볼 수 있을까요?
안녕하세요선생님께서 강의하시는 강의별 전체 코드를 받아볼 수 있는 git 주소가 있을까요?전체 정답 코드를 보지 못하고 따라하다보니 에러가 많이 나서 선생님 것으로 확인해보고자 합니다. 그럼 답변 기다리겠습니다. 감사합니다.
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
맛집 클릭시 상세조회 부분에서 오류가 생겨요ㅜㅜ
return에서 기존 hello 문구를 지우고 엔터를 치면 여기서 부터 오류가 떠요 그리고 이렇게html에서 js로 옮기는 과정에서 오류가 뜨는데 어떻게 해야되나요?
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
메인페이지 헤더 회원/비회원 표시
로그인이나 회원가입 후 메인페이지 헤더 부분에 비회원과 회원 구분하는 바가 나오지 않습니다.header.js코드는 그대로 복붙하고 url 에서 포트만 3001 -> 3000 으로 바꿨습니다 back end의 indexRoute에서 아래app.get("/jwt", jwtMiddleware, index.readJwt); 코드도 잘 추가하였는데 문제가 어떤건지 모르겠습니다 ㅠㅠ
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
swagger 3 질문입니다.(Step 24)
안녕하세요 springboot 3에서는 swagger 2를 이용할 수 없더라구요.( 추가로 강의자료에서 제공해주신 springfox3 버전을 이용해도 index.html에 접속이 되질 않아 springdoc으로 진행하는 상황입니다.)그래서 springdoc, swagger3를 사용하여 http://localhost:8088/swagger-ui/index.html로 들어가 실습을 진행하고 있습니다.강의자료를 참고하여 springfox형식을 springdoc에 맞춰 작성하여 info, contact,license 까지 확인할 수 있었습니다. 그런데 produce,consume 부분을 구현하지 못했는데 springdoc에서는 produce,consume이 없어진건가요? 아니면 다른 방법이 있을까요? 강의자료는 springfox 기준이라서 아직 produce, consume 부분을 해결하지 못한 상태입니다.package com.example.restfulwebservice.config; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @Configuration public class SwaggerConfig { private static final Contact CONTACT = new Contact().name("Kenneth Lee") .url("http://www.joneculsting.co.kr") .email("edowon@joneconsluting.co.kr"); private static final License LICENSE= new License().name("Apache 2.0") .url("http://www.apache.org/licenses/LICENSE-2.0"); private static final Info INFO = new Info().title("Awesome API Title") .contact(CONTACT) .description("Awesome API Documentation") .version("1.0") .license(LICENSE) .termsOfService("urn:tos"); private static final Set<String> DEFAULT_PRODUCES_AND_CONSUMES = new HashSet<>(Arrays.asList("application/json", "application/xml")); @Bean public OpenAPI springShopOpenAPI() { return new OpenAPI().info(INFO).; } }
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part6: 웹 서버
HelloMessage.Message 프로퍼티 여부에 따른 다른 동작
선생님 안녕하세요! 최신 버전의 VS2022 .NET7.0 환경에서도 실습이 잘 되어서 너무 기분이 좋습니다. c# 문법인지 잘 모르겠지만... 이해가 안 가는 것이 있어 질문 올립니다.'Hello MVC #1' 강의 14:29에서 다음과 같이 작성하셨습니다.public string Message { get; set; }하지만, { get; set; }을 하지 않고 아래와 같이 작성public string Message;하면 앞으로 모든 실습에서 Message가 null이 됩니다. 디버그에서 특별한 에러도 나타나지 않습니다.강의 내용대로 프로퍼티를 붙이면 간단히 해결할 수 있지만 이 차이가 무엇인지 자세히 알고 싶습니다. 프로퍼티를 사용한 경우프로퍼티 없이 선언만 한 경우
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
강의에서 배운 상품 CRUD를 RESTAPI 로 바꾸기
강의에서 배운 상품 CRUD를 RESTAPI로 바꿔보고 싶은데, 이게 해볼만한 시도일까요? 참조할만한 자료가 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
N:M 등록 / 조회 API
query{ fetchProduct(productId:"7967c808-532f-48e8-87b7-4f4536ab1903"){ id name description price isSoldout productSaleslocation{ id address addressDetail lat lng meetingTime } productCategory{ id name } productTags{ id name } } } { "errors": [ { "message": "Cannot return null for non-nullable field Query.fetchProduct.", "locations": [ { "line": 2, "column": 3 } ], "path": [ "fetchProduct" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "Error: Cannot return null for non-nullable field Query.fetchProduct.", " at completeValue (C:\\Users\\enter\\OneDrive\\바탕 화면\\agarang-camp\\19-01-typeorm-crud-many-to-many\\node_modules\\graphql\\execution\\execute.js:594:13)", " at C:\\Users\\enter\\OneDrive\\바탕 화면\\agarang-camp\\19-01-typeorm-crud-many-to-many\\node_modules\\graphql\\execution\\execute.js:486:9", " at processTicksAndRejections (node:internal/process/task_queues:96:5)", " at async Promise.all (index 0)", " at execute (C:\\Users\\enter\\OneDrive\\바탕 화면\\agarang-camp\\19-01-typeorm-crud-many-to-many\\node_modules\\apollo-server-core\\src\\requestPipeline.ts:501:14)", " at processGraphQLRequest (C:\\Users\\enter\\OneDrive\\바탕 화면\\agarang-camp\\19-01-typeorm-crud-many-to-many\\node_modules\\apollo-server-core\\src\\requestPipeline.ts:407:22)", " at processHTTPRequest (C:\\Users\\enter\\OneDrive\\바탕 화면\\agarang-camp\\19-01-typeorm-crud-many-to-many\\node_modules\\apollo-server-core\\src\\runHttpQuery.ts:436:24)" ] } } } ], "data": null } 똑같이 따라헀는데, fetchproduct 부분에서 왜 이런 오류가 발생하는 것일까요? product.entity.ts 를 아래와 같이 nullable: true로 수정했는데도 플레이 그라운드에서 똑같은 에러가 나옵니다. ======================== import { Field, Int, ObjectType } from '@nestjs/graphql'; /* eslint-disable prettier/prettier */ // product.entity.ts import { ProductCategory } from 'src/apis/productCategory/entities/productCategory.entity'; import { ProductSaleslocation } from 'src/apis/productsSaleslocation/entities/productSaleslocation.entity'; import { ProductTag } from 'src/apis/productTags/entities/productTag.entity'; import { User } from 'src/apis/users/entities/user.entity'; import { Column, DeleteDateColumn, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToOne, PrimaryGeneratedColumn, } from 'typeorm'; @Entity() @ObjectType() export class Product { @PrimaryGeneratedColumn('uuid') @Field(() => String) id: string; @Column() @Field(() => String) name: string; @Column() @Field(() => String) description: string; @Column() @Field(() => Int) price: number; @Column({ default: false }) //시작시 디폴트값 @Field(() => Boolean) isSoldout: boolean; // soldedAt: Date // @Column({ default: false }) //시작시 디폴트값 // @Field(() => Boolean) // isDeleted: boolean; // @Column({ default: null }) //시작시 디폴트값 // @Field(() => Date) // DeletedAt: Date; @DeleteDateColumn() @Field({ nullable: true }) deletedAt: Date; @JoinColumn() @OneToOne(() => ProductSaleslocation) @Field(() => ProductSaleslocation) productSaleslocation: ProductSaleslocation; @ManyToOne(() => ProductCategory) @Field(() => ProductCategory) productCategory: ProductCategory; @ManyToOne(() => User) @Field(() => User, { nullable: true }) user: User; @JoinTable() @ManyToMany(() => ProductTag, (productTags) => productTags.products) @Field(() => [ProductTag]) productTags: ProductTag[]; } /*tag가 배열이다 그래프QL에서 배열은 양쪽으로 감싸는 게 배열이다. */ 위 product.enttity.ts를 수정한 이유는 DB에 deletedAt 컬럼이 null, userId 컬럼이 null로 되어 있어서 아래와 같이 추가해주었습니다. 그래도 똑같은 에러가 발생하네요. @Field({ nullable: true }) deletedAt: Date; @ManyToOne(() => User) @Field(() => User, { nullable: true }) user: User;
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
1:1 관계 등록 API 질문입니다.
//18-03의 방법 2. 상품과 상품 거래위치를 같이 등록하는 경우 async create({ createProductInput }) { const { productSaleslocation, ...product } = createProductInput; console.log( '어떻게 받아오는지 createProductInput:::::::::찍어보자 ', createProductInput, ); console.log( '서비스단에서 productSaleslocation::::::::', productSaleslocation, ); // console.log('서비스단에서...product:::::::::::::::', ...product); const result = await this.productSaleslocationRepository.save({ ...productSaleslocation, // }); console.log('서비스단에서 result:::::', result); const result2 = await this.productRepository.save({ ...product, productSaleslocationId: result.id, }); console.log('서비스단에서 result2:::::', result2); return result2; } 위를 grpahql 에서 데이터를 전송해보면, 터미널창에서아래와 같이 나옵니다. 어떻게 받아오는지 createProductInput:::::::::찍어보자 [Object: null prototype] { name: '마우스', description: '참좋은마우스', price: 2000, productSaleslocation: [Object: null prototype] { address: '구로', addressDetail: '구로역', lat: 1, lng: 1, meetingTime: 2022-10-30T00:00:00.000Z } } 서비스단에서 productSaleslocation:::::::: [Object: null prototype] { address: '구로', addressDetail: '구로역', lat: 1, lng: 1, meetingTime: 2022-10-30T00:00:00.000Z } query: START TRANSACTION query: INSERT INTO `product_saleslocation`(`id`, `address`, `addressDetail`, `lat`, `lng`, `meetingTime`) VALUES (?, ?, ?, ?, ?, ?) -- PARAMETERS: ["f6bc848d-42ff-42c5-a454-39e8a9106dac","구로","구로역",1,1,"2022-10-30T00:00:00.000Z"] query: COMMIT 서비스단에서 result::::: { address: '구로', addressDetail: '구로역', lat: 1, lng: 1, meetingTime: 2022-10-30T00:00:00.000Z, id: 'f6bc848d-42ff-42c5-a454-39e8a9106dac' } query: START TRANSACTION query: INSERT INTO `product`(`id`, `name`, `description`, `price`, `isSoldout`, `deletedAt`, `productSaleslocationId`, `productCategoryId`, `userId`) VALUES (?, ?, ?, ?, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT) -- PARAMETERS: ["a09e9c56-4b45-420d-98ec-c075da6014e0","마우스","참좋은마우스",2000] query: SELECT `Product`.`id` AS `Product_id`, `Product`.`isSoldout` AS `Product_isSoldout`, `Product`.`deletedAt` AS `Product_deletedAt` FROM `product` `Product` WHERE ( `Product`.`id` = ? ) AND ( `Product`.`deletedAt` IS NULL ) -- PARAMETERS: ["a09e9c56-4b45-420d-98ec-c075da6014e0"] query: COMMIT 서비스단에서 result2::::: { name: '마우스', description: '참좋은마우스', price: 2000, productSaleslocationId: 'f6bc848d-42ff-42c5-a454-39e8a9106dac', deletedAt: null, id: 'a09e9c56-4b45-420d-98ec-c075da6014e0', isSoldout: false } 어떻게 받아오는지 createProductInput:::::::::찍어보자 [Object: null prototype] { name: '마우스', description: '참좋은마우스1', price: 2000, productSaleslocation: [Object: null prototype] { address: '구로', addressDetail: '구로역', lat: 1, lng: 1, meetingTime: 2022-10-30T00:00:00.000Z } } 서비스단에서 productSaleslocation:::::::: [Object: null prototype] { address: '구로', addressDetail: '구로역', lat: 1, lng: 1, meetingTime: 2022-10-30T00:00:00.000Z } query: START TRANSACTION query: INSERT INTO `product_saleslocation`(`id`, `address`, `addressDetail`, `lat`, `lng`, `meetingTime`) VALUES (?, ?, ?, ?, ?, ?) -- PARAMETERS: ["33a4c94a-886d-4f76-9226-a363afc4b7e4","구로","구로역",1,1,"2022-10-30T00:00:00.000Z"] query: COMMIT 서비스단에서 result::::: { address: '구로', addressDetail: '구로역', lat: 1, lng: 1, meetingTime: 2022-10-30T00:00:00.000Z, id: '33a4c94a-886d-4f76-9226-a363afc4b7e4' } query: START TRANSACTION query: INSERT INTO `product`(`id`, `name`, `description`, `price`, `isSoldout`, `deletedAt`, `productSaleslocationId`, `productCategoryId`, `userId`) VALUES (?, ?, ?, ?, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT) -- PARAMETERS: ["a97bb588-3074-4f1b-abaf-a9d244616dd3","마우스","참좋은마우스1",2000] query: SELECT `Product`.`id` AS `Product_id`, `Product`.`isSoldout` AS `Product_isSoldout`, `Product`.`deletedAt` AS `Product_deletedAt` FROM `product` `Product` WHERE ( `Product`.`id` = ? ) AND ( `Product`.`deletedAt` IS NULL ) -- PARAMETERS: ["a97bb588-3074-4f1b-abaf-a9d244616dd3"] query: COMMIT 서비스단에서 result2::::: { name: '마우스', description: '참좋은마우스1', price: 2000, productSaleslocationId: '33a4c94a-886d-4f76-9226-a363afc4b7e4', deletedAt: null, id: 'a97bb588-3074-4f1b-abaf-a9d244616dd3', isSoldout: false } 강의에서 설명해주신 코드는 const result2 = await this.productRepository.save({ ...product, productSaleslocation: result, }); console.log('서비스단에서 result2:::::', result2); return result2; }...product를 하면 product 테이블에 product와 관련된 데이터(name, description, price) 가 DB 테이블에 들어가는 것은 이해가 되었는데, productSaleslocation: result 라고 하면, DB에lnt, lng, meetingtime, address, adressDetail까지 전부 들어가는 게 아닌가요? 왜 DB를 확인해보면, productSaleslocation의 id 값만 productSaleslocationId 컬럼에 들어가게 되는 것인가요? 그래서 product 테이블에 productSalesloactionId 라는 컬럼이 있어서 아래와 같이 result2 코드를 작성해보았습니다. const result2 = await this.productRepository.save({ ...product, productSaleslocationId: result.id, }); 이렇게 코드를 작성하면, 상품테이블에 productSaleslocationId 컬럼이 있으니, productSaleslocationId : result.id 를 해줘서 DB에 productSaleslocationId 값을 넣을 수 있는게 왜 아닌지 이해가 가지 않습니다.왜 productSaleslocationId : result.id 라고 하면 터미널창에는 찍히지만,DB에 아무것도 들어가지 않는 것일까요?오히려 productSaleslocation: result 라고 하면, productSaleslocation의 lnt, lng, meetingtime, address, adressDetail 은 하나도 들어가지 않고, 어떠한 에러가 발생하지 않고, productSaleslocation의 id값만 외래키로 DB에 잘 들어가게 되는것일까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
PartialType과 OmitType 동시 적용
포트폴리오 과정의 'N:M 등록 및 조회/회원가입'을 처리하는 중 질문할 것이 나와 질문을 드립니다.User의 생성부분을 구현하기 위해 CreateUserInput 타입을 만들었고 해당 부분에서 유저 아이디, 패스워드, 이메일 등을 기입하도록 하였습니다.@InputType() export class CreateUserInput { @Field(() => String) loginId: string; @Field(() => String) @MinLength(8) password: string; @Field(() => String) name: string; @Field(() => String) address: string; @Field(() => String) @IsPhoneNumber('KR') phone: string; @Field(() => String) @IsEmail() @Transform(({ value }) => value.toLowerCase()) email: string; } 그리고 User의 수정 부분을 구현하기 위해 UpdateUserInput 타입을 만들었습니다. 단순히 OmitType으로 CreateUserInput 부분을 넘겨 만들었습니다만, API 동작에서 패스워드 부분을 넘기지 않으면 필수 항목을 입력하지 않았다고 수정이 되지 않았습니다. @InputType() export class UpdateUserInput extends OmitType(CreateUserInput, ['loginId', 'email'], InputType) { } 그래서 그냥 PartialType까지 상속하고 싶었습니다만 타입스크립트도 다중 상속을 지원하지 않는지 OmitType과 PartialType을 함께 쓸 수 없었습니다. 이러면 그냥 CreateUserInput처럼 전부 구현할 수 밖에 없나요? API 부분에서 넘기지 않은 부분은 그냥 그대로 냅두는 것을 목적으로 합니다.