[OSSCA] #63 엔드포인트 리팩토링 - 1. 소스코드 분석

뚜비·2022년 8월 17일
0

2022 OSSCA

목록 보기
10/14

2022 오픈소스 컨트리뷰션 아카데미 "NHN Toast Power Platform Connector" Masters에 참여하면서 배운 내용을 기록하였습니다.



❌문제발생 - Repo를 clone하고 VsCode로 켰는데 엄청난 에러가 발생

CS0246 : 'type/namespace' 형식 또는 네임스페이스 이름을 찾을 수 없습니다. using 지시문 또는 어셈블리 참조가 있는지 확인합니다.

CS0518 : 미리 정의된 형식 ‘type’을(를) 정의하지 않았거나 가져오지 않았습니다.

대부분 이런 에러들이었다.


✅ 해결 방법
처음에는 README.md에서 로컬 개발환경을 보고 Docker Desktop이 필요한가? 해서 Docker Desktop을 설치했는데.. 여전히 에러가 떴다. 계속 Docker image 만들어야 하나!?! 아니면 .net 삭제하고 다시 설치해야 하나?! 하고 쓸데없는 고민을 했다..


참고자료와... 다른 멘티분들의 도움으로... dotnet restore 명령어를 치면 해결된다는 것을 알았다.. 즉, using에 사용되는 패키지들, 모든 종속성들이 아직 빌드가 안 되서 참조할 수 없던 것!!

종속성 복원

프로젝트를 만들거나 복제하는 경우 포함된 종속성은 프로젝트 빌드 시까지 다운로드되거나 설치되지 않습니다. dotnet restore 명령을 실행하여 프로젝트 파일에 지정된 프로젝트 특정 도구뿐만 아니라 종속성도 수동으로 복원할 수 있습니다. 대부분의 경우 명령을 명시적으로 사용할 필요가 없습니다. new, build 및 run과 같은 명령을 실행하면 필요한 경우 NuGet 복원이 암시적으로 실행됩니다


심지어 내 1주차 정리 노트에 해결방법이 있었음..

?????????????어이가 없네


dotnet restore

The dotnet restore command uses NuGet to restore dependencies as well as project-specific tools that are specified in the project file.
한글



✅ Code 분석

src > nt-common > Models

모든 API에서 공통적으로 사용할 수 있는 Request path, query, header, url Options과 Response body, header, 해당 객체 클래스로 이루어져 있다.

src > nt-sms > Models



Models 폴더는 Triggers에 존재하는 각 API request의 path, query, option, resopnse에 대한 데이터들을 정의한 클래스가 있다.



src > nt-sms > Triggers

Azure Functions

  • OpenAPI를 등록하는 과정이 포함되어 있음 - 링크
  • HttpTrigger : Http request와 함께 해당 함수를 호출한다.

field

  • ToastSettings< SmsEndpointSettings > settings
    : 각 class 하나당 EndPoint 하나가 존재한다.
    : ToastSettings< T >는 endpoint 객체를 get, set할 수 있는 클래스
    : SmsEndpointSettings< T >는 각 종류(Trigger 종류)의 endpoint 객체를 get,set할 수 있는 클래스

  • IValidator< *RequestQueries > validator
    : 각 endpoint 객체의 requestQueries의 validation을 확인하는 클래스

  • IHttpClientFactory factory
    : 주어진 논리적 이름으로 커스텀 설정을 한 System.Net.Http.HttpClient instance를 생성하는 클래스

  • ILogger< T > log
    : 범주 이름이 지정된 TCategoryName 유형 이름에서 파생되는 로깅을 위한 일반 인터페이스


Task Run

GetMessage를 보고 분석하였다 .

public async Task<IActionResult> Run( // async메서드는 반드시 void 또는 Task 또는 Task<T>를 반환
            [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "messages/{requestId:regex(^\\d+\\w+$)}")] HttpRequest req,
            string requestId)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");
 		
        	/*Get header and Validate*/
            var headers = default(RequestHeaderModel); // reference인 경우 null, numeric인 경우 0을 반환 
            try
            {
                headers = req.To<RequestHeaderModel>(useBasicAuthHeader: true).Validate();
                // useBasicAuthHeader를 true로 설정
                // 여기서 appKey와 secretKey를 얻고 validation 확인  
                // headers = await req.To<RequestHeaderModel>(SourceFrom.Header).Validate().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                return new BadRequestResult();
            }

			/*Get queries and Validate*/
            var queries = default(GetMessageRequestQueries);
            try 
            {
                queries = await req.To<GetMessageRequestQueries>(SourceFrom.Query).Validate(this._validator).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                return new BadRequestResult();
            }

			/*Get path*/
            var paths = new GetMessageRequestPaths() { RequestId = requestId };

			/**/
            var requestUrl = new RequestUrlBuilder()
                .WithSettings(this._settings, this._settings.Endpoints.GetMessage)
                .WithHeaders(headers)
                .WithQueries(queries)
                .WithPaths(paths).Build();

            this._http.DefaultRequestHeaders.Add("X-Secret-Key", headers.SecretKey);
            var result = await this._http.GetAsync(requestUrl).ConfigureAwait(false);

            var payload = await result.Content.ReadAsAsync<GetMessageResponse>().ConfigureAwait(false);

            return new OkObjectResult(payload);
        }

모든 Trigger들은 다음과 같은 Workflow를 따른다.

1. Get Header and Validate

  • RequestHeaderModel.cs : nt-common > Models 안에 있다. 즉 appkey랑 secretkey를 get or set한다.
  • To< RequestHeaderModel > : HttpRequestExtensions 클래스의 메소드, httpRequest에서 appkey, secretkey를 얻는다.
  • Validate : nt-common > Validators > RequestHeaderValidator 메소드, appKey와 SecretKey가 null인지 공백인지 확인

2. Get Queries(or Body) and Validate

  • RequestQueries.cs(or RequestBody) : nt-sms > Models 안에 있다. 각 endpoint마다 필요한 query(Body)를 get or set한다.
  • To< T > : HttpRequestExtensions 클래스(metadata)의 메소드, sourceForm을 지정해준다.
  • Validate : nt-sms > Validators > 각 endpoint의 RequestQueryValiators 메소드

3. Set Path or Set Options

  • GetMessageRequestPaths : RequestId를 set한다.
  • ListSenders : 여러 옵션 변수를 헤더나 쿼리로부터 set한다.

4. Build request URL and Send request

  • RequestUrlBuilder : endpoing 객체를 setting하고 header, query, path를 setting하고 url을 build한다.
  • 인증을 위한 secretKey를 추가하고 GetAsync 함수는 해당 URL로 GET request를 보낸다. PostAysnc 함수는 해당 URL로 Post request를 보낸다.


5. Read Response

  • ReadAsAsync< T > 를 통해 응답 객체를 받는다
    GetMessage의 경우는 위의 내용을 받는다.


profile
SW Engineer 꿈나무 / 자의식이 있는 컴퓨터

0개의 댓글