inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

graphql에서 restapi로 변경

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

안녕하세요! 강의에서 nestjs와 graphql로 구현을 하셨는데요, 이 걸 restapi로 바꿔서 구현해보고자 합니다. 지금 일단은 강의코드에서 api를 rest로 하나씩 바꿔보는중인데 혹시 typeORM이나 nest내의 다른 설정들도 바꿔야만 하는지 간략하게나마 가이드해주시면 감사하겠습니다!

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
nya 댓글 1 좋아요 0 조회수 324

Join시 정의하는 테이블 명이 entity에 있는것이 맞을까요?

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

product.service.ts에서 join을 하기 위해 return this.productsRepository.find({ relations: ['productSaleslocation']}) 이렇게 해주었는데요. 여기에 들어가는 productSaleslocation이라는 테이블 명이 product.entity.ts에서 조인이 되는 대상 컬럼 @JoinColumn() @OneToOne(() => ProductSaleslocation) @Filed(() => ProductSaleslocation) productSaleslocation: ProductSaleslocation 이 부분의 정의 때문에 그렇게 명명하는 것일까요? relation에 들어가는 테이블명은 딱히 정의한 곳을 못찾아서요. 실제 DB상의 테이블 명이랑은 다르고... 만약 제 추측이 맞다면 @OneToOne, @MayToOne을 붙인 Filed명이 테이블 명 처럼 사용되는 것이죠?

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
yisi 댓글 1 좋아요 0 조회수 258

async, await를 사용하는 이유?

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

product.service.ts에서 create, findOne, findAll을 만들때는 async, await를 사용하지 않았습니다. 그리고 create 만들 때 nest에서는 이걸 호출하는 곳(resolver)에서 자동으로 기다리고 있기 때문이라고 하셨는데요. 다만, 시간이 걸리기 때문에 Return type은 Promise<Product>로 했고요. 근데 update, delete를 하실때는 async, await를 사용하셨는데요. 어떤 이유가 있을까요??

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
yisi 댓글 1 좋아요 0 조회수 463

안녕하세요 선생님, 제가 강의를 다듣고 난후 코드랑 학습자료보고 복습식으로 공부하는게 좋을것 같아서요, 혹시 수업시간에 작성한 예제코드들은 어디서 받을수 있나요?

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

안녕하세요 선생님, 제가 강의를 다듣고 난후 코드랑 학습자료보고 복습식으로 공부하는게 좋을것 같아서요, 혹시 수업시간에 작성한 예제코드들은 어디서 받을수 있나요?

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
댓글 1 좋아요 0 조회수 362

안녕하세요!

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

훈훈한 Javascript 섹션4-for문과 while문 마지막 예제에서 let i = 0; while(i < 10) { console.log(i) i = i + 1 } 결과 10이 출력되는건 반복 횟수이고 0~9 까지 출력이 맞는거 같은데 확인 부탁드립니다!

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
댓글 2 좋아요 0 조회수 282

HttpExceptionFilter에 단순 HttpException 예외처리도 필요하지 않나요?

해결됨

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

HttpExceptionFilter에서 에러처리시 exception.getStatus() 로 err 변수값을 넣을떄 HttpException 의 경우 string 타입 BadRequestException, UnauthorizedException 와 같이 미리 정의된 경우 { message: any; statusCode: number } 타입 class-validator의 경우 { error: string; statusCode: 400; message: string[] } 타입의 3가지 형태가 되는데 이번강의에서 string 타입 자체를 제거하셧는데 HttpException 를 사용하게되면 에러 메시지가 제대로 안 날라 가게 됩니다. class-validator를 도입하면서 HttpException 케이스를 제거 하신거 같은데 해당 예외도 포함은 되어있어야 하지 않나요? class-validator 가 완전히 HttpException 를 대체하게 한다면 HttpException를 사용못하게 막을 방법이 있을까요? import { ExceptionFilter, Catch, ArgumentsHost, HttpException, } from '@nestjs/common'; import { Response } from 'express'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const status = exception.getStatus(); const err = exception.getResponse() as | string | { message: any; statusCode: number } | { error: string; statusCode: 400; message: string[] }; //class-validator if (typeof err !== 'string' && err.statusCode === 400) { return response.status(status).json({ success: false, code: err.statusCode, data: err.message, }); } //HttpException if (typeof err == 'string') { return response.status(status).json({ success: false, code: status, data: err, }); } //BadRequestException, UnauthorizedException return response.status(status).json({ success: false, code: status, data: err.message, }); } }

  • node.js
  • express
  • nestjs
  • typeorm
최석우 댓글 1 좋아요 0 조회수 375

module.ts에서도 process.env 대신 configService를 사용할수 있나요?

해결됨

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

이전강의떄 app.module.ts에서 외부에서 Env값을 불러오는 방법도 있다는것을 알려주셧는데 const getEnv = async () => { //외부에 저장된 Env값 // const response = await axios.get("/loadEnv") // return response.data; return { DB_PASSWORD: '~~~', }; }; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, load: [getEnv] }), UsersModule, ChannelsModule, DmsModule, WorkspaceModule, TypeOrmModule.forRoot({ type: 'mariadb', host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT, 10), username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: ['entities/*.js'], // autoLoadEntities: true, // TypeOrmModule.forFeature 내의 entities를 읽어서 자동 연결 synchronize: true, logging: true, keepConnectionAlive: true, //핫리로딩시 연결종료 방지 charset: 'utf8mb4', }), ], controllers: [AppController], providers: [AppService, ConfigService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(LoggerMiddleware).forRoutes('*'); } } @Injectable() export class AppService { constructor(private configService: ConfigService) {} getHello() { return this.configService.get('PORT'); } } 제가 이해한 바에 따르면 app.module.ts 에서 ConfigModule을 임포트하여 app.service.ts에서 ConfigService를 사용하여 외부 env값을 사용할수 있는데 app.module.ts 에서도 자체적으로 외부env를 이용하여 db설정값을 지정할수 있는지 궁금합니다.

  • node.js
  • express
  • nestjs
  • typeorm
최석우 댓글 1 좋아요 0 조회수 378

JPA 최적화 강의 수강 후, 개인 프로젝트 수행하면서 생긴 질문입니다.

해결됨

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

안녕하세요. JPA 최적화 강의를 수강하고, 개인적으로 DDD를 책으로 공부해본 후에 개인 토이 프로젝트를 진행하던 중, 뜻밖에 의문이 생겼는데 여쭐 곳이 없어서 이렇게 질문 올리게 되었습니다. 맨 땅에 헤딩으로 이런저런 강의, 책, 다른 분들의 소스를 참고 하려다보니 여러 개념이 뒤섞여서 혼동이 옵니다.. ㅠㅠ 현재 프로젝트에서는 크게 에그리거트를 CUSTOMER, EXTERNAL, SECURITYMEDIA 3개로 나누어 설계했는데요. 강의에서도, 책에서도 DOMAIN 계층에 있는 서비스는 해당 도메인에 대한 순수한 CRUD를 수행하는 것으로 보았습니다. DDD 책에서는 여러 에그리거트가 필요로 하는 기능을 구현할 때는 도메인 서비스로 구현하라고 이야기 했구요. 처음에는 책에서 조언하는 대로 도메인 서비스로 구현해보고자 하다가, 좀처럼 구현이 안되어서 다른 분들이 구현한 소스를 참조하다 보니 application(응용)영역을 FACADE라는 상위 계층을 두는 것을 방식을 알게 되었습니다. 소스를 따라가보니 각 애그리거트의 DOMAIN 영역에 있는 서비스를 주입하여, 각 도메인 영역에 있는 서비스를 적절히 호출하기에 책에서 본 도메인 서비스와 같은 역할을 하겠구나 하여,, 해당 프로젝트 구성 방식을 따라 개발해보기로 했습니다. 그런데 개발을 하다보니,, 참조하는 소스에서 메소드 단위의 트랜잭션의 적용을 facade 영역이 아닌, 도메인 영역의 서비스 구현체에서 하는 것을 알게 되었습니다. 제가 개발하고자 기능은 여러 애그리거트를 생성, 변경하는 하나의 행위가 하나의 트랜잭션으로 묶여야 하는데 말이죠. 이러한 이유 때문에 현재 소스는 FACADE에서는 하나의 도메인 영역의 서비스를 주입하여 하나의 메소드를 호출하도록 되어있고, 도메인 영역에 있는 해당 서비스의 구현체에서 여러 애그리거트의 서비스, 레포지토리를 주입받아 하나의 메소드에서 트랜잭션 단위로 수행하도록 구현되어있습니다.. @Service @RequiredArgsConstructor public class SecurityMediaFacade { private final SecurityMediaService securityMediaService; public SecurityMediaInfo.Main registerOtp(SecurityMediaCommand.RegisterSecurityMediaRequest req) { //디지털otp 발급 // 디지털 otp 발행 return securityMediaService.issueSecurityMedia(req, SecurityMediaType.DIGITAL_OTP); } ... } public interface SecurityMediaService { public SecurityMediaInfo.Main issueSecurityMedia(SecurityMediaCommand.RegisterSecurityMediaRequest req, SecurityMediaType type); ... } @Slf4j @Service @RequiredArgsConstructor public class SecurityMediaServiceImpl implements SecurityMediaService { private final CustomerReader customerReader; private final SecurityMediaStore securityMediaStore; private final TokenStore tokenStore; private final ExternalClientService externalClientService; @Override @Transactional public SecurityMediaInfo.Main issueSecurityMedia(SecurityMediaCommand.RegisterSecurityMediaRequest req, SecurityMediaType type) { // 요청고객 찾기 Customer customer = customerReader.findCustomerByRnn(req.getRnn()); SecurityMedia newOtp = null; if(!customer.existActiveSecurityMedia()) { // otp 신규 SecurityMedia initOtp = req.toEntity(SecurityMediaType.DIGITAL_OTP, customer); newOtp = securityMediaStore.store(initOtp); // 토큰 발급 요청 Token newToken = externalClientService.getToken(customer, newOtp); newOtp.addToken(newToken); tokenStore.store(newToken); } return new SecurityMediaInfo.Main(newOtp); } 위에는 프로젝트의 구성인데.. 첫 단추부터 잘못 끼운 것도 같아서 시작 단계인 지금에서라도 좀 개선을 해보려고 하는데요. 사실 도메인 서비스가 제가 의도로 하는 여러 애그리거트의 서비스 기능을 묶어서 하는 건지 아무리 읽어봐도 혼선이 옵니다. 혹시 DDD 책에서 이벤트라는 개념이 나오는데 도메인 서비스가 아니라, 이 이벤트를 통해 다른 애그리거트의 응용 서비스를 호출하도록 핸들링 하는게 올바른 방법일까요? 지금과 같은 구조를 유지해도 된다면.. facade 영역의 메소드를 트랜잭션으로 묶고, 각 도메인 계층의 서비스들에서 선언된 해당 도메인에 대한 crud 메소드를 적절히 호출해가면서 facade 영역에서 비즈니스 로직을 처리해도 될까요? 너무 글이 장황하고 기네요.. ㅠㅠ 혹시 도움을 주신다면 너무나도 감사드리겠습니다.

  • java
  • spring
  • spring-boot
  • jpa
인생은회전목마 댓글 1 좋아요 0 조회수 510

백엔드부터 해도 되나요???

미해결

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

git에서 소스 안받고 강의보면서 직접 타이핑해가면서 학습하려고 합니다. 백엔드 강의부터 진행해도 문제 없을까요?

  • node.js
  • express
  • nestjs
  • typeorm
tlawofyd1 댓글 1 좋아요 0 조회수 344

터미널 명령어에서 특수문자를 일반 택스트로 인식시키는 방법이 있나요?

해결됨

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

mysql의 비밀번호를 자동생성을 통해 생성해서 ~+kmisB1[@l1&FH 로 설정해 놓았는데 아래 명령어에서 특수문자로 인해 인식이 정상적으로 못하는것 같습니다. & 앞에 \를 추가하여 ~+kmisB1[@l1\&FH 로 시도해도 인식이 되지 않았습니다. 명령어 : npx typeorm-model-generator -h localhost -d sleact -u root -x ~+kmisB1[@l1&FH -e mysql 에러 : 필수 인자를 받지 못했습니다: e 'FH'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다.

  • node.js
  • express
  • nestjs
  • typeorm
최석우 댓글 2 좋아요 0 조회수 671

객체가 스스로의 리스트를 가지고, 양방향 매핑을 해도 될까요?

해결됨

자바 ORM 표준 JPA 프로그래밍 - 기본편

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? ( 예 /아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? ( 예 /아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? ( 예 /아니오) [질문 내용] 악! 스프링 웹 개발은 즐거워! 김영한 선생님 질문있습니다. 선생님의 두 로드맵을 거의 다 듣고 그를 바탕으로 포폴용 게시판을 만들어보고 있습니다. 와중 댓글과 대댓글 기능을 구현하는 과정에서 Comment라는 객체를 만들고 객체의 타입을 Comment와 reply로 나누었습니다. 특정 게시판에 관한 데이터를 불러올 때 댓글과 대댓글을 편리하게 불러오기 위해 타입이 Comment인 객체가 reply에 해당하는 객체를 리스트로 갖도록 설계했습니다. 이후 테스트를 진행해보았는데 fetch join을 통한 데이터 로드는 문제 없이 진행되었습니다. 다만 이러한 설계 방식이 올바른지에 대한 질문을 스스로 해결할 수 없어서 글 남깁니다. 아래는 코드와 테스트 코드 및 실행 결과이고, 마지막에 질문이 있습니다. package toy.board.domain.post; import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.util.StringUtils; import toy.board.domain.BaseDeleteEntity; import toy.board.domain.user.Member; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PROTECTED) @EqualsAndHashCode(callSuper = true) public class Comment extends BaseDeleteEntity { public static final int CONTENT_LENGTH = 1000; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "comment_id", nullable = false) private Long id; @Column(name = "content", nullable = false, length = CONTENT_LENGTH) private String content; @Column(name = "type", nullable = false, updatable = false) private CommentType type; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "post_id", nullable = false, updatable = false) private Post post; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id", nullable = false, updatable = false) private Member member; @OneToMany(mappedBy = "parent") private List<Comment> replies = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_comment_id", updatable = false) private Comment parent; /** * 양방향 관계인 Member와 Post에 대해 자동으로 양방향 매핑을 수행한다. */ public Comment( @NotNull final Post post, @NotNull final Member member, @NotNull final String content, @NotNull final CommentType type ) { this.post = post; this.member = member; this.content = content; this.type = type; } public boolean update(final String content) { if (!StringUtils.hasText(content)) { return false; } this.content = content; return true; } public void leaveReply(Comment reply) { if (areTypesCorrectThisAnd(reply)) { throw new IllegalArgumentException("주어진 댓글과 대댓글의 타입이 올바르지 않습니다."); } if (hasComment(reply)) { throw new IllegalArgumentException("대댓글이 이미 다른 댓글에 포섭되어 있습니다."); } if (isNew(reply)) { throw new IllegalArgumentException("댓글이 이미 해당 대댓글을 포함하고 있습니다."); } this.replies.add(reply); reply.parent = this; } private boolean isNew(Comment reply) { return this.replies.contains(reply); } private static boolean hasComment(Comment reply) { return reply.parent != null; } private boolean areTypesCorrectThisAnd(Comment reply) { return this.type != CommentType.COMMENT || reply.type != CommentType.REPLY; } } @Transactional @DisplayName("comment가 List<comment>를 갖고, fetch join으로 가져올 수 있는가?") @Test public void comment_has_comments_fetch_join() throws Exception { //given Member member = Member.builder( "member", new Login("password"), Profile.builder("nickname").build(), LoginType.LOCAL_LOGIN, UserRole.USER ).build(); em.persist(member); Post post = new Post(member, "title", "content"); em.persist(post); Comment comment = new Comment(post, member, "comment", CommentType.COMMENT); em.persist(comment); for (int i = 0; i < 5; i++) { Comment reply = new Comment(post, member, "reply" + String.valueOf(i), CommentType.REPLY); comment.leaveReply(reply); em.persist(reply); } em.flush(); em.clear(); //when QComment reply = new QComment("reply"); List<Comment> findComments = queryFactory .selectFrom(QComment.comment) .leftJoin(QComment.comment.replies, reply).fetchJoin() .where( QComment.comment.post.id.eq(post.getId()), QComment.comment.type.eq(CommentType.COMMENT) ) .fetch(); System.out.println("============================================="); for (Comment findComment : findComments) { System.out.println("findComment.getId() = " + findComment.getId()); System.out.println("findComment.getContent() = " + findComment.getContent()); } //then Comment findComment = findComments.get(0); for (Comment findReply : findComment.getReplies()) { System.out.println("findReply content = " + findReply.getContent()); } } [테스트 실행 시 create query] create table comment ( is_deleted boolean default false not null, type tinyint not null check (type between 0 and 1), comment_id bigint generated by default as identity, created_date timestamp(6), deleted_date timestamp(6), last_modified_date timestamp(6), member_id bigint not null, parent_comment_id bigint, post_id bigint not null, content varchar(1000) not null, created_by varchar(255), last_modified_by varchar(255), primary key (comment_id) ) [테스트 실행 결과] select c1_0.comment_id, c1_0.content, c1_0.created_by, c1_0.created_date, c1_0.deleted_date, c1_0.is_deleted, c1_0.last_modified_by, c1_0.last_modified_date, c1_0.member_id, c1_0.parent_comment_id, c1_0.post_id, r1_0.parent_comment_id, r1_0.comment_id, r1_0.content, r1_0.created_by, r1_0.created_date, r1_0.deleted_date, r1_0.is_deleted, r1_0.last_modified_by, r1_0.last_modified_date, r1_0.member_id, r1_0.post_id, r1_0.type, c1_0.type from comment c1_0 left join comment r1_0 on c1_0.comment_id=r1_0.parent_comment_id where c1_0.post_id=? and c1_0.type=? ===================== findComment.getId() = 1 findComment.getContent() = comment findReply content = reply0 findReply content = reply1 findReply content = reply2 findReply content = reply3 findReply content = reply4 [질문] 제가 궁금한 것을 자세히 말하자면, 테이블이 만들어질 때, comment 테이블의 특정 row(대댓글인 컬럼)가 해당 테이블의 다른 row(댓글인 row)의 PK값을 FK로 갖는데, 댓글에 해당하는 row는 객체가 생성되고 DB에 저장될 때 해당 컬럼에 null이 저장됩니다. 이는 Comment 객체의 ID에 @GenerateValue 설정을 주어서 그렇습니다. 위의 상황은 실무에서 사용할만큼 적절한가요? 아니라면 대안이 있을까요? jpa와 관련된 질문을 읽다보니, 다대일 관계에서 left join fetch의 경우 where문의 결과에 따라 데이터 일관성의 오류가 나타날 수 있다는 답변이 있었습니다.(해당 글: https://www.inflearn.com/questions/15876/fetch-join-%EC%8B%9C-%EB%B3%84%EC%B9%AD%EA%B4%80%EB%A0%A8-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4 ) 제가 작성한 테스트 코드의 쿼리문은 일대다 관계에서 일에 해당하는 엔티티에 별칭을 주어 where문을 적용한 것이므로 일관성의 문제가 발생하지 않는다고 생각했는데 이것이 옳은 생각인가요? 마지막으로 쿼리의 복잡도와 쿼리 개수는 trade off 관점에서, 특정 게시물에 관한 데이터를 반환해야 하는 api 요청이 들어왔을 때, 게시물과 댓글 엔티티가 단방향 관계일 경우 게시물에 관한 데이터와 댓글 및 대댓글에 관한 데이터를 각각의 저장소를 통해 가져오는 것이 좋을까요 혹은 쿼리가 다소 복잡해지더라도 한 번에 가져오는 것이 좋을까요? 아니면 단방향 관계를 양방향으로 만드는 것이 더 나은 선택일까요? 혼자 공부하니 올바른 방식을 찾는게 참으로 어려운 것 같습니다. 답변 기다리겠습니다. 감사합니다.

  • java
  • jpa
김민규 댓글 1 좋아요 0 조회수 388

msa환경에서 서버끼리는 gRPC로 통신을 하는 형태로 만들어보려고 합니다.

미해결

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

안녕하세요. 이번에 신입으로 입사한 주니어 개발자입니다. 입사한 회사에서 msa환경에서 서버끼리는 gRPC통신를 이용해서 통신을 하고 클라이언트와는 게이트웨이를 통해서 통신하는 프로젝트를 nest.js를 이용해서 만드는 온보딩 미션을 주셨는데요. 공식문서를 계속 읽어보고 하는데 아직 gRPC와 msa환경을 처음 접해서 그런가 만들어보려니 감이 잡힐거같으면서도 어렵네요. 먼저 nest.js의 기본적인 http로 통신하는 시스템을 만들어보고 그 이후에 리팩토링해서 요구조건을 만족하게 만드는게 나을까요?

  • node.js
  • express
  • nestjs
  • typeorm
뱅준 댓글 1 좋아요 0 조회수 440

docker volume 설정 시 mount 에러

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

영상에서 알려주신대로 파일을 설정하고 실행하면 다음과 같은 에러가 발생합니다. 잘 안보일 수 있어서 아래에 적습니다. Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/run/desktop/mnt/host/e/Study-App/codecamp-backend/class/section04/04-07-docker-compose-with-mongoose-board2/backend/index.js" to rootfs at "/myfolder/index.js": mount /run/desktop/mnt/host/e/Study-App/codecamp-backend/class/section04/04-07-docker-compose-with-mongoose-board2/backend/index.js:/myfolder/index.js (via /proc/self/fd/9), flags: 0x5000: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type 결국 경로를 못찾는다는 얘기로 이해했는데요. 그래서 yaml파일을 다음과 같이 고쳐봤습니다. 그러면 실행이 되는 것처럼 나오지만 이러한 에러가 발생합니다. 근데 이상한건 다른 터미널에서 docker ps를 실행하면 다음과 같이 하나만 실행된 것처러럼 나오는데... 막상 현재 실행되고 있는 터미널에서 ctrl + c를 하면 다음과 같이 2개가 중지되는걸로 나옵니다. 어디서부터 잘못된 걸까요 ㅠ_ㅠ

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
yisi 댓글 3 좋아요 0 조회수 3577

좋아요나 조회수 등 동시성 처리 질문입니다.

미해결

재고시스템으로 알아보는 동시성이슈 해결방법

사용자가 많지 않고 일반 커뮤니티 같은 경우에는 좋아요 개수가 많이 몰릴 일이 없다고 생각해서 PessimisticLock을 적용하려고 합니다. 제가 생각했을 땐 인스타나 그런 대규모 사이트의 좋아요는 PessimisticLock을 적용하면 성능 저하가 뚜렷하게 나타난다고 생각합니다. -> 레디스 사용이 베스트 토이프로젝트 규모의 SNS는 PessimisticLock으로 구현하는게 비용도 들지 않고 데이터 정합성이 보장된다고 판단했습니다. 혹시 제가 틀린 거나 더 나은 방법이 있을까요? 항상 감사합니다! 아 추가로 newFixedThreadPool은 왜 32로 설정하는지도 궁금합니다!!

  • java
  • spring
  • 동시성
진짜 잘하고싶다 댓글 1 좋아요 1 조회수 953

nodejs mysql 도커 컴포즈관련해서 문의 드립니다

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

docker-compose.yml파일의 코드는 이렇게 구성하였는데요 도커컴포즈하면 mysql데이터 가져오고싶은데 어떻게 해야하나요? volume으로 해봤는데 해당 데이터들은 못가져오고 새로 table을 생성되는데 이렇게 구성되어있습니다 main스키마의 table들을 가져오고싶습니다. 이렇게해봤는데도 원하는대로 데이터를 가져오지못했습니다 mysql연결도 안되는 상황입니다 어떻게 해야 해결할수있을까요?

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
밈몀묘 댓글 1 좋아요 0 조회수 352

궁금한 사항

해결됨

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

강의보던중 front 도 시작하시는걸봤는데 프론트없어도 클론코딩할 수 있는건가요??

  • node.js
  • express
  • nestjs
  • typeorm
진승이 댓글 1 좋아요 0 조회수 270

docker-compose의 image 옵션 사용시 docker가 1개만 만들어집니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

docker-compose.yaml에서 강의대로 소스를 수정했습니다. 그 후 yarn add mongoose를 하고 index.js를 수정한 후 그리고 docker-compose build를 했는데요. my-backend는 만들어졌는데 my-database가 만들어지지 않습니다. my-database 부분은 아예 실행조차 하지 않은것처럼 보이는데요. 구글에서도 잘 찾아지지 않아 질문 드립니다.

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
yisi 댓글 1 좋아요 0 조회수 504

제네레이트 마이그레이션 오류

해결됨

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

yujinseung@yujinseung-ui-MacBookPro slack_nest % npm run db:generate-migration > study_nest@0.0.1 db:generate-migration > npm run typeorm migration:generate -- ./src/migrations -d ./dataSource.ts > study_nest@0.0.1 typeorm > typeorm migration:generate ./src/migrations -d ./dataSource.ts Error during migration generation: Error: Unable to open file: "/Users/yujinseung/Desktop/slack_nest/dataSource.ts". Cannot use import statement outside a module at CommandUtils.loadDataSource (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/CommandUtils.js:22:19) at async Object.handler (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/MigrationGenerateCommand.js:68:26) yujinseung@yujinseung-ui-MacBookPro slack_nest % npm run db:migrate > study_nest@0.0.1 db:migrate > npm run typeorm migration:run -- -d ./dataSource.ts > study_nest@0.0.1 typeorm > typeorm migration:run -d ./dataSource.ts Error during migration run: Error: Unable to open file: "/Users/yujinseung/Desktop/slack_nest/dataSource.ts". Cannot use import statement outside a module at CommandUtils.loadDataSource (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/CommandUtils.js:22:19) at async Object.handler (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/MigrationRunCommand.js:41:26) 위 두 오류가 뜹니다..! 뭐가문제일까요..ㅠㅠ

  • node.js
  • express
  • nestjs
  • typeorm
진승이 댓글 1 좋아요 0 조회수 483

섹션 29 10-1 Entity 구현 선행 강좌

해결됨

[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스

섹션 28에서는 스타벅스를 가지고 ERD 까지 그렸는데, 섹션 29에서 새로운 ERD를 가지고 Entity 구현하는 것 같네요. 강의가 업데이트가 안된걸까요?

  • javascript
  • node.js
  • express
  • docker
  • tdd
  • rest-api
  • nestjs
박호정 댓글 2 좋아요 0 조회수 415

인기 태그

인프런 TOP Writers

주간 인기글