👩🏻‍💻 TIL

Code first, dbContext 개념

ji-hyun 2022. 4. 22. 23:28

typesafe 프로그래밍 언어의 장점에 대해 많은 글이 작성되었습니다. 

하지만 Typesafe 방식으로 GraphQL 스키마를 구축한다는 것은 무엇을 의미합니까? 

GraphQL 스키마의 코드 우선 구현(code first implementation)은 어떤 모습입니까? 

 

 

 

우리는 GraphQL과 같은 기술을 사용하여 React 웹 애플리케이션과 백엔드 서비스를 연결합니다.

 

 

 

우리는 Nexus 라는 라이브러리와 함께 코드 우선 접근 방식을 사용하여 GraphQL 스키마를 개발합니다. 

Nexus 문서에서는 type safe 방식으로 GraphQL 스키마를 개발하는 방법에 대해 설명하고 있으며 오늘은 이것이 개발 측면에서 의미하는 바를 보여줍니다.

 

 

 

여기서 code first 라는 것이 무엇일까요?

 

 

 

일단 위에랑 직접적인 관련은 아니지만 위로 개념을 올린 김에 ORM 을 봅시다.

C#과 같은 객체 지향형 프로그래밍 언어에서 데이터베이스를 쉽게 사용하기 위한 도구라고 한 줄로 말할 수 있습니다.

 

즉, OOP개념의 객체(Object)와 관계(Relation)형 DB의 테이블을 맵핑(Mapping)해서 (native)SQL 작성을 안하고 쉽게 DB의 데이터에 Access 할 수 있는 기술이라고도 할 수 있습니다.

 

https://poiemaweb.com/js-object-oriented-programming

 

참고.
자바스크립트는 강력한 객체지향 프로그래밍 능력들을 지니고 있다. 간혹 클래스가 없어서 객체지향이 아니라고 생각하는 사람들도 있으나 프로토타입 기반의 객체지향 언어다.
자바스크립트는 클래스 개념이 없고 별도의 객체 생성 방법이 존재한다.
객체, Object(), 생성자, 함수..

자바스크립트는 이미 생성된 인스턴스의 자료구조와 기능을 동적으로 변경할 수 있다는 특징이 있다.
객체 지향의 상속, 캡슐화(정보 은닉) 등의 개념은 프로토타입 체인과 클로저 등으로 구현할 수 있다.

클래스 기반 언어에 익숙한 프로그래머들은 이러한 프로토타입 기반의 특성으로 인해 혼란을 느낀다.
자바스크립트에서는 함수 객체로 많은 것을 할 수 있는데 클래스, 생성자, 메소드도 모두 함수로 구현이 가능하다.

 

 

 

 

다시 말해 ORM에서 쓰는 핵심 단어는 Object / Relation / Mapping 입니다. (까먹지 말고..)

 

 

 

 

 

 

<Entity Framwork 모델>

크게 3가지가 있다고 합니다.

 

1. Code First

2. Model First

3. Database First   

 

 

 

Model First와 Database First 접근 모델

Visual Studio 의 Visual Model Designer (EDMX) 를 통해 객체/테이블 매핑을 디자인 하는 방식으로,

 

두 개간 차이점 Database Frist는 기존 DB로 부터 테이블 구조를 읽어와서 디자이너를 통해 Visual Model로 구성되는 것을 말하고 

Model First는 기존 DB가 없을 때 직접 Model Designer를 써서 Entity들을 추가해 가면서 모델을 구성하는 방식입니다. 

위 두가지는 Visual Model Designer로 디자인한 것을 edmx 파일에 저장하게 됩니다.

 

 

 

Code First 방식은 Model Designer / EDMX를 사용하지 않고 데이터 모델을 C# 클래스로 직접 코딩하는 방식으로 앞으로의 EF는 Code First 방식만을 지원한다고 합니다.

 

 

 

 

 

 

 

< Code First >

C# 클래스로 테이블의 구조를 정의하고 클래스의 프로퍼티를 테이블 컬럼으로 맵핑합니다.

Code First란 말 그대로 DB를 미리 설계하지 않고 C# 클래스로 Domain Object(Model???) 를 정의하고 

프로그램 실행 시 DB가 없으면 자동으로 DB를 생성하는 방식을 취한다

 

 

-> 이 말은 코드 우선이니까 테이블 모델이 Code 기반에서 생성되고 DB에 대한 생성과 추가 수정이 Code 기반의 Class Model 에서 된다는 것을 말합니다!!!!

 

 

 

MS SQL의 management studio를 통해 추가/수정/설정을 하는 것이 아니라 code로 구현해서 DB 관리자가 설정하는 것 처럼 추가하고 변경 사항을 할 수 있다는 것을 말합니다.

 

 

 

 

 

 

 

 

 

 

 

Code First 를 활용하는 부분을 보다보면 크게 3가지가 나옵니다.

 

1. DbContext

2. Fluent API

3. Data Annotation

 

위 내용을 깊게 들어가면 EF로 DB Table 추가하고 컬럼 변경 및 키지정 관계 지정 까지 프레임워크 사용법 까지 다루게 되어서 저런게 있다는 것만 간략히 말하겠습니다.

 

DbContenxt 는 간단히 System.Data.Entity의 클래스 이며 DB와 관련된 여러 API를 사용할 수 있다는 것을 말합니다.

 

 

Context란 말에서 뭔가 저장소 Repository 란 단어가 생각나는데 Domain Classes 와 Database의 중간에 있는 녀석으로 생각하면 될 것 같습니다.

 

 

 

 

 

간단히 제가 쓰는 dbContext 예시를 들어보면 다음과 같습니다.

 

export interface Context {

  request: Request;

  response: Response;

  prisma: PrismaClient;

  prismaRO: PrismaClient;

  pubsub: PubSub;

  // mqttClient: AsyncMqttClient;

  mqttClient: MqttClient | null;

  asyncMQTTPublish: AsyncClient;

  mongoClient: mongoClient.MongoModel;

  // danbiAuth(ctx: Context): DanbiAuth;

  // auth(): Promise<DanbiAuthType>;

  authorized: Auth;

  processUpload(file: FileUpload, type: string): Promise<ProcessUploadData>;

  processDelete(name: string, type: string): Promise<string>;

  getUser(context: Context): Promise<User | null>;

  getUserRequest(request: Request, prisma: PrismaClient): Promise<User | null>;

  getAdAuthAction(fas: string, iv: string): FasType | null;

  verifyToken(token: string): boolean;

 

 

 

 

 

 

 

Context 에 대해 더 깊이 파고들고 싶어서 더 찾아보았습니다.

https://pro9dan.tistory.com/entry/Context-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

 

 

다시 정리

개발자라면 context 라는 단어를 한번쯤은 모두 접해 보았을 것입니다. 그런데 context가 뭘까요

누군가 이렇게 물어본다면 딱히 대답하기가 힘들죠. 사용만 할 줄 알지 정확히 개념이 서지 않아서 그렇습니다.

 

 

서블릿은 누군가에 의해 한번 호출되어 로드되거나 혹은 서블릿엔진 시작시에 로드(load) 될 수 있습니다. 

한번 로드된 서블릿은 메모리에 로드된 채 남아 있습니다. 이 때 또 다시 다른 사람에 의해 그 서블릿이 호출되면 

file에서 다시 읽어들이는 것이 아니라 이미 로드된 서블릿을 사용하여 빠르게 응답하게 됩니다.

 

 

 

Context 란 용어는 어떤 한글번역본에는 "문맥"이란 용어로 직역됩니다만 사실 적절한 의미전달은 안되고 있습니다. 

C++ 언어에서 보면, Print을 하기 위해 PrintContext 객체를 사용하고, Java Applet에서 Applet의 AppletContext를 얻기 위해 Applet.getAppletContext()를 사용하지요. 

결국 "Context"란 "어떤 객체를 핸들링하기 위한 접근 수단"의 의미를 가집니다. 

위에서 해당 서블릿을 수행하려면 "서블릿 Context"를 획득해야 그것을 통해 그 서블릿을 수행할 수 있는 것이지요.

 

 

서블릿은 CGI와는 다르게 멀티쓰레드(Multi-thread)로 동작합니다. 

한 순간에 하나의 수행만 있는 것이 아니라, 같은 서블릿이 여러 client의 호출에 대해 동시다발적으로 같이 수행되는 구조이지요.

 

 

 

 

 

DbContext가 DB 전체를 관리할 수 있는 API를 제공하는 느낌이라면 

Fluent API는 Table에 대한 설정을 할 수있다 테이블 간의 관계나 키 설정과 관련된 매서드들을 사용할 수 있습니다.

Data Annotation은 C#의 Attribute로 컬럼의 값에 대한 Data Validation이나 컬럼의 속성(기본키(Key, notMapped))에 대해 프로터티 바로 위에 지정할 수 있습니다.

즉 DB 제어 / Table 제어 같은 것이지 않겠나

 

 

 

 

마지막으로

Code-First Model에서 다른 Table과의 관계에 대한 표현은 크게 3가지가 있습니다.

 

1. 1:1 관계

2. 1:N 관계

3. N:M 관계

 

자세한 관계에 대한 설명은 여기서 중요한 것은 아니니 생략하겠습니다.

 

 

 

 

 

 

 

 

다시 돌아와서

https://resilient-tech.medium.com/code-first-graphql-with-nexus-2f2a01aa371d

 

 

우리는 GraphQL과 같은 기술을 사용하여 React 웹 애플리케이션과 백엔드 서비스를 연결합니다. 

우리는 Nexus라는 라이브러리와 함께 코드 우선 접근 방식을 사용하여 GraphQL 스키마를 개발합니다. 

Nexus 문서에서는 타입 안전 방식으로 GraphQL 스키마를 개발하는 방법에 대해 설명하고 있으며 오늘은 이것이 개발 측면에서 의미하는 바를 보여줍니다. 

또한 Prisma(데이터 액세스 계층)와 Nexus 간의 통합으로 확장하여 타입 안전성 아이디어를 완전히 수용할 것입니다.

 

 

 

 

 

 

 

'👩🏻‍💻 TIL' 카테고리의 다른 글

npm 과 npx 차이  (0) 2022.05.14
graphQL 예외처리  (0) 2022.05.08
Git 커밋 없이 Checkout 하면 어떤 일이 일어날까?  (0) 2022.03.23
git merge (fast-faward, 3-way Merge)  (0) 2022.03.20
Git 기초부터 브랜치까지  (0) 2022.03.20