Development note/C#

[C#] 콘솔로 RestAPI 서버를 만드는 방법

v명월v 2020. 7. 17. 13:49

안녕하세요. 명월입니다.


이 글은 C#에서 콘솔로 RestAPI 서버를 만드는 방법에 대한 글입니다.


RestAPI란 먼저 Web 프로토콜을 사용하여 고유 URL에 대한 결과 값을 얻는 방식을 말합니다. Web 프로토콜의 메서드는 GET, POST 뿐 아니라 PUT, DELETE까지 넣어 사용하고 결과는 Json 형식의 결과를 받는 것이 일반적입니다.

기본적으로 RestAPI는 Web 프로토콜을 사용하기 때문에 IIS에서 사용하는 것이 일반적입니다만, 어플리케이션에서도 API를 제공하기 위해 RestAPI를 구축할 수 있습니다.


먼저 비주얼 스튜디오를 실행해서 Console 프로젝트를 실행합니다.

콘솔 프로젝트를 만들고 먼저 라이브러리 추가를 합시다. 필요한 라이브러리는 Newtonsoft.Json과 System.ServiceModel, System.ServiceModel.Web이 있습니다.

Newtonsoft.Json는 Nuget으로 라이브러리를 다운 받아서 연결합니다.

System.ServiceModel, System.ServiceModel.Web의 경우는 .Net Framwork 라이브러리이기 때문에 그냥 Reference 참조로 라이브러리를 참조합니다.


그리고 먼저 App.config을 수정합니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <!-- 기본 설정 .Net Framework 버전 설정. 따로 설정할 필요는 없다. -->
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <!-- 바인딩 설정  -->
    <bindings>
      <webHttpBinding>
        <binding name="webHttp" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="01:00:00" maxBufferPoolSize="2147483647">
          <security mode="None">
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <!-- 서비스 설정 -->
    <services>
      <!-- 서비스 클래스 설정 -->
      <service name="RestAPITest.Service">
        <!-- 서비스 인터페이스 설정 -->
        <endpoint address ="rest" binding="webHttpBinding" bindingConfiguration="webHttp" contract="RestAPITest.IService" behaviorConfiguration="web"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehaviour">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

참조 - https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/system-servicemodel

참조 - https://docs.microsoft.com/en-us/dotnet/framework/wcf/configuring-services-using-configuration-files

사실 저도 이것 저것 참조해서 작성한 거라 정확한 내용을 잘 모르겠네요. 위 도큐멘트를 보시고 필요한 부분이 있으면 추가하면 될 껏 같습니다.


그리고 App.config에 지정했던 서비스 인터페이스와 클래스를 만듭니다.

using System.ServiceModel;
using System.ServiceModel.Web;
namespace RestAPITest
{
  // 서비스 지정
  [ServiceContract]
  public interface IService
  {
    [OperationContract]
    // 메소드 지정과 리턴 포멧 지정(리턴 포멧은 RestAPI를 만들 것이기 때문에 Json으로 한다.)
    // UriTemplate에 보간법으로 중괄호로 값을 지정할 수 있다.
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/data/{value}")]
    // 이 어트리뷰트를 설정하지 않으면 기본 함수명을 키로 리턴이 됩니다. 여기서는 키를 value로 지정했다.
    [return: MessageParameter(Name = "value")]
    // 리턴을 String으로 해도 상관없는데.. 여기서는 클래스 형식한다.
    // 클래스 형식으로 하면 자동으로 Newtonsoft.Json 라이브러리를 통해 자동으로 Json 형식으로 변환한다.
    Response GetResponse(string value);
  }
  // 그냥 String이로
  public class Response
  {
    // 프로퍼티
    public string Result { get; set; }
  }
}
namespace RestAPITest
{
  // 구현 함수
  public class Service : IService
  {
    // /data/{value}의 형시긍로 접속되면 호출되어 처리한다.
    public Response GetResponse(string value)
    {
      // Response 클래스 타입으로 리턴하면 자동으로 Json형식으로 변환한다.
      return new Response() { Result = "echo - " + value };
    }
  }
}
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;

namespace RestAPITest
{
  class Program
  {
    // 실행 함수
    static void Main(string[] args)
    {
      // 서버 인스턴스 생성
      var server = new WebServiceHost(typeof(Service));
      // EndPoint 설정
      server.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
      // 서버 기동
      server.Open();
      // 콘솔 출력
      Console.WriteLine("Server start.");
      // 엔터 키를 누르면 종료 메시지.
      Console.WriteLine("If you want exit this application, please push enter key.");
      // Main 함수가 끝나면 프로그램이 종료되니, 서버 스레드가 움직일 수 있도록 대기 한다.
      Console.ReadLine();
    }
  }
}

위 소스를 작성하고 실행하겠습니다.

RestAPI는 콘솔에서 조작하는 것이 아니고 웹으로 접속해서 결과를 받는 것이기 때문에 브라우저로 접속하겠습니다.

일단 기본 루프 페이지를 들어가면 EndPoint를 찾을 수 없다고 나옵니다.

/data/test로 접속하게 되면 route를 따라 Service의 GetResponse 함수가 호출됩니다. 여기 함수에서 test의 값을 value의 파라미터로 받아서 Response 클래스를 인스턴스 생성합니다.

Response의 인스턴스의 Result 값은 echo - test로 리턴이 됩니다.

참고로 IService에서 MessageParameter값을 value로 설정했기 때문에 value의 키로 json값이 출력이 됩니다.


여기까지 C#에서 콘솔로 RestAPI 서버를 만드는 방법에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.