[.NET]Swagger에서 Namespace를 이용하여 API 버전 구분(그룹화)하기

API를 개발 하다보면 자연스럽게 생기는 대표적인 고민이 바로 버전 관리 이다.

예를 들어

  1. 버전을 개별 기능(URL) 별로 관리 할 것인가? 아니면 개별 기능을 구룹화하여 구룹별로 할 것인가?
  2. 버전에 대한 URL 설계는 어떻게 할 것인가?
  3. 버전 관리를 한다면 구버전 지원은 어떻게 할 것인가? 

등등…

이러한 고민들을 Swagger의 MultipleApiVersions을 이용하여 멀티 버전을 설정하면 해결 할 수 있다.

API APP 프로젝트를 만들면 다음과 같은 경로에 SwaggerConfig.cs라는 파일을 볼 수 있다. (위차: ~/App_Start/SwaggerConfig.cs)

클릭해서 열어보면 대략 Line:35 정도에 c.SingleApiVersion 이라는 것이 기본으로 설정되어 있는 것을 볼 수 있는데 이것은 API APP프로젝트를 처음 만들면 API 샘플(~/Controller/ValueController.cs) 1개가 등록 되어 있기때문에 멀티 버전 관리를 할 수 있는게 없기 때문이다.

멀티 버전을 관리 설정을 하기 전에 우선 간단히 아래 그림과 같이 2개의 API를 만들어 보도록 하겠다.
(프로젝트 샘플 소스를 가지고 실제 기능은 없고 단순히 호출 할 수 있는 Method만 만들었다. Student – ClassRoom: 학생 API / Teacher – Report :  선생님 API)

위와 같이 구성하면, 각각의 컨트롤러 파일의 Namespace는 
Student : SwaggerFramework.Controllers.Student
Teacher : SwaggerFramework.Controllers.Teacher

로 설정 된 것을 확인 할 수 있다.

이제 위와 같이 설정된 Namespace를 가지고 API 버전을 구분 할 수 있도록 MultipleApiVersions를 설정해 보자.

앞서 언급한 SwaggerConfig.cs라는 파일을 열어 Line:35 정도에 있는 c.SingleApiVersion으로 이동하여, 해당 줄을 삭제(보통 주석 해두는 것이 좋다.)하고 아래와 같이 코드를 추가 하도록 한다.

//c.SingleApiVersion("v1", "SwaggerFramework");
c.MultipleApiVersions((apiDesc, targetApiVersion) =>
{
   var controllerNamespace = apiDesc.ActionDescriptor.ControllerDescriptor.ControllerType.FullName;
	
   if(CultureInfo.InvariantCulture.CompareInfo.IndexOf(controllerNamespace, string.Format(".{0}.", targetApiVersion), CompareOptions.IgnoreCase) >= 0)
   { 
	return true; 
   }
   return false;
},(vc) =>
{
   vc.Version("Student", "Student API v1");
   vc.Version("Teacher", "Teacher API v1");
});

위와 같이 설정하면 각 Namespace(Student, Teacher)이름에 따라서 버전이 구분을 할 수 있다. 

실제로 구분이 되는지 프로젝트를 실행 해보면 다음 그림과 같이 API가 Namespace 별로 구분되어 확인 할 수 있다.

Swagger Explore 창에 Namespace를 이용하여 검색해보면, SwaggerConfig.cs에 설정해 둔 각 API설명과 해당 Namespace를 가지고 있는 API 기능을 구별하여 확인 할 수 있다.
(Explore 검색 예시 – http://{ Domain Path }/swagger/docs/[ Studnet | Teacher ])

이와 같이 Swagger의 환경 설정에서 Namespace를 이용하면 간단히 API를 버전별로 구분(그룹화)하여 제공 할 수 있기 때문에 버전관리를 쉽게 할 수 있다. 

[.NET]Swagger를 이용하여 Azure API APP 문서 만들기

Swagger를 사용하면 개발된 Restful API에대한 스팩을 별도의 문서를 만들지 않고도 자동으로 문서화 하여 웹형태로 쉽게 제공 할 수 있다.

먼저, Swagger에서 제공하는 API 스팩 문서 화면을 살펴 보자.

Rest API의 URL(Route 주소)목록을 제일 먼저 볼 수 있는데, 직관적으로 해당 API APP에 어떤기능들 있는지 한번에 파악 할 수 있게해준다. 특정 URL을 클릭하면 그 API안에 구현된 HTTP Method 리스트를 볼 수 있다.

Restful API의 동작은 동일한 Route 주소에 HTTP Method를 통해서 CRUD(생성 – Post, 조회 – Get, 변경 – Put, 삭제 – Delete)기능을 구분하며 이러한 구분을 Swagger에서는 4가지 색으로 구분하여 표현해준다.

다음으로, Get Method를 클릭하여 Swagger에서 해당 API에 대한 문서를 어떻게 제공하는지 실제 코드랑 비교하 살펴보자.

Swagger Source Code

// GET api/values/5
[SwaggerOperation("GetById")]
[SwaggerResponse(HttpStatusCode.OK)]        
[SwaggerResponse(HttpStatusCode.NotFound)]
public string Get(int id)
{
    return "value";
}

Swagger Document

첫 번째, 최상단의 GET /api/Values/{id}는 Rest API를 호출하기 위한 라우트 주소로 메서드 역할을 정의하는 public string Get(int id) 의 정보이다.

두 번째, 최상단 바로 및의 Parameters영역은 API의 메서드의 변수에 대한 설명을 확인 할 수 있으며, Value 필드에 임의 값을 넣고 테스트 해볼 수 도 있다. 
(값을 넣고 아래 Try it Out! 이라는 버튼을 누르면 개발한 API가 동작한다.)

마지막, Response Messages영역은 API가 HTTP통신을 할때 반환하는 HttpResponseMessage의 HTTP State Code에 대한 정의이다. Swashbuckle의 속성 설정 방법을 통해서 정의 할 수 있다.
(예: [SwaggerResponse(HttpStatusCode.OK)], [SwaggerResponse(HttpStatusCode.NotFound)])

Restful API를 개발하는 사람이라면 시각화가 되어 있지 않은 API의 각종 정보들을 다른 사람에게 전달하기 정말 까다로운 일이라는 것을 알고 있을 것이다. 이런 고충을 Swagger Framework을 통해서 해소 할 수가 있다. 

Azure의 APP API서비스는 Swagger Framework을 기본으로 제공해 주고 있어서 Azure에서 API를 개발 할 때, 몇가지 정의 방법으로 인터페이스 설명 및 기본 설정을 하면, Swagger.UI에서 보기 좋게 문서화 해서 Web으로 잘 보여 준다. 그래서 개발자가 문서 작업때문에 시간들일 필요도, 머리 아플일도 전혀 없다. 그리고 표준 Rest API 정의에 대한 표현을 Swagger에서 정말 잘 다루고 있기 때문에 어느정도 Rest API에 대한 인식이 있다면 API를 제공받은 사람 입장에서도 서비스에 대한 정보를 별다른 노력 없이 쉽게 인식할 수 있다. 

[.NET]Azure API APP에서 Swagger Framework 바로 사용하기

기존 웹프로젝트에 Swagger Framework을 사용하려면 프레임웍 패키지를 다운받아 설치하고 Swagger 실행을 위한 몇몇의 Config 셋팅을 하는 수고를 했어야 했다. 그런데 Azure에서 제공하는 Azure API APP Service 프로젝트를 생성하면 기본 셋팅으로 Swagger Framework이 설치 및 기본 셋팅이 되어 있는 것을 NuGet 패키지 관리자에 들어가 보면 다음과 같이 확인 할 수 있다.

기본 설치가 되어 있기 때문에 별다른 걱정 없이 바로 쓰기만 하면 된다.
정말인지 확인하기 위해서 새프로젝트를 만든뒤 바로 실행 해보자.

!?!? 권한이 없단다. 
이런 403.14 페이지를 보는 이유는 API는 Application Programming Interface이기 때문에 UI(User Interface)가 없기 때문이다. 그렇다면 어떻게 API에 대한 정보를 볼 수 있을 것인가? 이럴때 Swagger가 제 역할을 한다.

당황하지 말고 주소의 주소에 Swagger라고 뒤에 추가 해보면 Swagger에서 제공하는 Swaager.UI를 경험할 수 있다.
(예: http://localhost:54499/ → http://localhost:54499/swagger)

아래 그림은 새 프로젝트 만들고 예제로 들어가 있는 샘플코드에 대한 화면이다. 

그림에서 보면 알 수 있듯이 Swagger.UI에서 제공하는 정보들은 개발된 API에 대한 스팩 문서들이다.
이 문서들은 API 스팩 문서로 별도의 문서를 작성하지 않아도 개발자가 개발하면서 주석으로 정의해 놓은(Swagger 문법?에 따라서) 것들을 Swagger.UI를 통해서 단번에 확인 할 수 있다.

[.NET]HttpResponseMessage 클래스 메서드 오류 CS1061 해결 방법

프로젝트에서 API를 호출하고 나서 결과를 읽어 Model(Object)에 담을때 다음과 같이 코드를 한다.

그런데 간혹 잘 코딩 했다고 생각을 했어도 다음과 같은 오류 메시지가 나올 때가 있다. 

오류 CS1061 ‘HttpContent’에는 ‘ReadAsAsync’에 대한 정의가 포함되어 있지 않고, ‘HttpContent’ 형식의 첫 번째 인수를 허용하는 확장 메서드 ‘ReadAsAsync’이(가) 없습니다. 
using 지시문 또는 어셈블리 참조가 있는지 확인하세요. 

이런경우 참조 패키지가 잘 준비되지 않은 경우이다. 
먼저 NuGet Package에 들어가서 System.Net.Http 버전을 최신버전으로 업데이트 하고,bMicrosoft.AspNet.WebApi.Client 패키지가 설치 되어 있는지 확인 해본다. 아마 안되어 있거나 구 번전일 것이다.

install-package Microsoft.AspNet.WebApi.Client

설치 및 업데이트가 완료 되었다면 문제 없이 작동 할 것이다.

Visual Studio Code에서 Team Service 연결하기

Visual Studio Code(이하 VSCode)는 MS에서 제공하는 간단한 코드 편집기로 기존의 Visual Studio(이하 VS)에서 하던 컴파일 기능이나 프로젝트 구성등의 기능은 없지만 Javascript나 Typescript 등 스크립트 언어를 편집하기에 최적화되어 있는 코드 편집기다.

개인적인 생각으로는 Azure에서 사용하는 JSON 기반의 Template 코드들을 쉽게 저작할 수 있는 기능을 서버 관리자에게 제공하고 싶어서 나온게 아닐까 생각한다. 아무래도 서버관리자가 기존의 VS를 사용하기에는 너무 무거운 시스템이라 시스템 자원 운용에 필요하는 스크립트 코드나 Template 코드를 관리하기에는 고비용이기에 다른 편기기 툴(Vim, Edit+, 메모장 등)들을 사용하고 있었기 때문이다.

VSCode에서 프로그래밍 코드를 편집할 수 있게 되면서, 자연스럽게 Visual Studio Team Service(이하 VSTS)로 형상 관리를 할 수 있게 되었는데, 그 방법은 간단하다.

다운로드 링크 – https://code.visualstudio.com/

처음 VSCode를 설치하고 열면 다음과 같이 화면이 나온다.

좌측 세로로 나와있는 메뉴바에서 위에서 3번째 Source Control 메뉴를 클릭하면 Source Control 패널이 나오는데 처음에는 아무것도 없으므로 상단에 (…) 모양의 버튼을 클릭하면 SCM Provider 추가하기 메뉴가 나와서 VSTS를 확장 설치할 수 있도록 도와준다.

간단히 Install 버튼을 누르고 나면 수초내에 확장 설치가 완료될 것이다. 그리고 Reload 버튼을 눌러서 VSCode를 재시작 해주면 VSTS를 사용할 확장설치는 완료 된다.

이제 VSTS에서 관리하는 Repository와 연결하기 위한 설정을 해야한다.
좌측 하단의 톱니바퀴 보양의 아이콘을 클릭하면 설정(Setting)메뉴를 볼 수 있다. 설정 메뉴에 들어가면 사용자 설정(User Settings)라는 환경설정 파일을 볼수 가 있는데 검색 창에 ‘location‘이라고 검색하여 tfvc.loation 변수를 찾아 TF.exe 파일의 경로를 설정해 준다.

여기서 유의해야 할 점은 VS버전마다 TF.exe위치가 다를 수 있다. 여기서는 Enterprise 버전을 사용하였으며, 경로는 값은 ‘C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer\\TF.exe‘ 이다.

이러면 Team Foundation Source Control을 실행할 상태가 되며, 다음으로는 local PC위치를 지정하여VSTS의 소스를 로컬에 저장할 공간을 선택한다.

셋팅이 완료 되면 다시 좌측 하단의 톱니바퀴를 클릭한다. 그러면 명령 팔레트(Command Palette)메뉴를 볼 수 있다. 명령 팔레트를 클릭하면 상단의 명령콘솔이 나오는데 VSTS에 로그인 하기위해 Team: Signin을 선택(Typing)한다. 그러면 VSTS에 접근할 수 있는 접근 토큰(Access Token)을 입력하는 곳이 나오는데 토큰을 입력하고 Sync를 수행하면 VSTS의 저장소에 있는 파일들을 로컬로 다운로드 한다.

싱크가 완료되면, VSCode와 VSTS가 연결이 완료된 것이다.
이제, VSCode에서도 프로그래밍 코드에 대한 형상 관리를 하면서 사용하면 된다.

-유의사항-
TF.exe 경로를 설정할때, 아래와 같은 오류 메시지가 보이는 경우가 있다.
(team) It appears you have configured a non-English version of the TF executable. Please ensure an English version is properly configured.

이것은 VSTS가 아직까지 다국어를 완벽하게 제공하는 것이 아니라 발생하는 것으로, 윈도우 언어 설정을 영문으로 변경하면 바로 해결된다.
(앞으로 업데이트 될 것으로 생각된다.)

서버 백업 / 복원하기

백업하기

전체 백업을 하기위해서 우선 루트 디렉토리로 간다.

$ cd /

tar을 이용해서 전체 백업을 한다.

$ sudo tar -cvpzf backup.tar.gz --exclude=/backup.tar.gz --one-file-system /

혹시 빼주고 싶은 파일이나 폴더가 있다면 exclude에 넣어주면된다.

--exclude=/[제외 폴더]

백업이 완료되면 루트 디렉토리 (/)에 backup.tar.gz이라는 파일을 볼 수 있다.
USB같은 외부 저장장치에 잘 보관해 두면 된다.

복구하기

루트 디렉토리에서 백업을 했기때문에 복구 할때도 루트 디렉토리에서 한다.

$ cd /

백업을 해두었던 tar파일을 압축을 풀어 복구한다.

$ tar xvpfz backup.tar.gz -C /

**앞에서 루트(/)디렉토리로 옮겨가라고 했지만 -C / 옵션을 사용한다면 다른곳에 저장되어 있어도 상관없다.

백업에서 제외햇던 디렉토리는 직접 만들어 준후 재부팅을 하면 복구가 완료된다.

$ reboot

추가 옵션 설명

​-z 압축 백업자료를 gzip을 이용하여 압축한다.
-c 생성 새로운 저장 파일을 만든다.
-v 수다 백업이 되고 잇는 파일 목록을 보여준다.
-p 퍼미션 보존 파일 보호를 위한 정보는 복구할 수 있도록 기억해 둔다.

Ubuntu에서 nvidia 그래픽 카드 드라이버 설치하는 방법

로그인 부팅하고 최초 로그인 화면에서 화면이 멈추다 깨지거나 로그인을 하고 x-window로드중에 시스템이 멈춰서 사용이 불가능 하는 경우, 그래픽 드라이버가 제대로 설치가 안된 것이다.

로그인 화면이 뜨는 순간 바로 Crtl + Alt + f1~6을 빠르게 눌러서 터미널 창에 접속한다.

(* 우분투도 2013년 4월25일 이후의 업데이트부터는 저장소에서 기본으로 지원합니다.)
그 다음 nvidia-current 패키지를 설치 하면 된다.

$ sudo apt-get install nvidia-current

재부팅을 하고 로그인을 하면 정상적으로 GUI환경에서 사용하실 수 있다.

USB 드라이브로 Ubuntu 설치 시 부팅이 되지 않을 때

USB로 우분투를 설치하는 경우, 부트로더에서 USB로 부팅을 하면 커서만 깜빡이고 진행이 멈춰버리는 증상이 나타날 때가 있다.

  1. USB이미지를 http://www.ubuntu.com에서 제공하는 툴로 설치 usb를 만든다.
  2. 윈도우 콘솔(cmd)을 띄운 후 diskpart를 입력하면 실행이 된다.
  3. list disk 명령어를 입력하면 현재 사용되고 있는 디스크 목록이 나온다.
  4. 목록 중 select disk #no 입력해서 우분투 설치 USB드라이브를 선택 한다.
  5. list partition 명령어를 입력하면 선택한 드라이브의 파티션 목록이 나온다.
  6. 목록 중 select parition #no 입력해서 설치 로더가 있는 파티션을 선택한다.
  7. active를 입력하고 list partition #no 하면 파티션 이름 앞에 *가 붙는다.
    (디스크 파티션이 활성화 되었다.)

다시 재부팅해서 USB로 부팅하면 설치가 잘 된다.

Can’t ssh localhost

ssh localhost를 하였을때, Read from socket failed: Connection reset by peer 라는 메시지가 튀어 나오면서 접속이 안되는 경우가 있다.

이경우 ssh_config파일을 죽어라 재설정 해도 잘 되지 않는다.
일단, 이 메시지가 나오면 포트를 확인해본다.

$ lsof -i:22

현재 LISTEN 상태인지 다른 프로세스하고 ESTABILISHED 되어 있는지 확인한다. 상태가 LISTEN이 아니거나 아무것도 안나오면 서버가 실행되지 않은것이고 다른 프로세스하고 ESTABILISHED되어있으면 해당 프로세스를 과감히 kill 해준다.

하지만

sshd    2750 root    3r  IPv4  15134      0t0  TCP *:ssh (LISTEN)
sshd    2750 root    4u  IPv6  15136      0t0  TCP *:ssh (LISTEN)

이런식으로 나올경우 서버 자체는 정상 작동하고 다른 프로세스하고는 연관이 없다. 그냥 재설치 하자.

재설치를 그냥 reinstall 옵션을 사용해도 좋지만 서버의 경우 설정파일이 그냥 남아 있는 경우가 있으므로, 제일 먼저 설정파일을 관리자 권한으로 모조리 삭제 해준다.

$ sudo rm /etc/ssh/sshd_config

그 다음은 purge 옵션으로 서버를 삭제 해주고 재설치를 하면 된다.

$ sudo apt-get purge openssh-server
$ sudo apt-get install openssh-server

이제 마지막으로 재부팅을 한후에 다시 실행하면 잘 접속 될 것이다.