계속·REST Web 서비스의 작성이 나에게는 너무 어려웠기 때문에, 누구에게나 알 수 있도록(듯이) 순서를 남긴다. (클라이언트편)

소개



마지막 기사의 연속입니다.

REST 웹 서비스 작성이 나에게는 너무 어려웠기 때문에 누구에게나 알 수 있도록 절차를 남긴다.

전회는 서비스측 프로그램의 작성과 동작 확인까지 실시했습니다만, 이번은 서비스측에 리퀘스트를 던지는 클라이언트측의 커멘드 프로그램을 만들어 보고 싶습니다.

전제



본 기사에서 작성한 프로그램의 실행은, 전회 작성한 서비스 프로그램 「ProductsApp」가 기동하고 있는 것을 전제로 하고 있습니다. ProductsApp을 만들고 시작하는 방법에 대한 자세한 내용은 마지막 기사을 참조하십시오.

본 기사에서 작성하는 프로그램의 I/F 사양



인수에 지정한 URL로 서비스측에 요구를 던지고, 서비스측으로부터 응답된 데이터를 표준 출력합니다.

프로그램 실행 예(명령 프롬프트)
>RestClient.exe http://localhost:51585/api/products/1
id: 1 name: Tomato Soup category: Groceries price: 1.0

1. 프로젝트 만들기



이번에는 명령으로 만들기 위해 콘솔 앱(.NET Framework)을 선택합니다. 이름은 "RestClient"로 둡니다.



2. JSON 시리얼 라이저 패키지 설치



NuGet 패키지 관리에서 System.Runtime.Serialization.Json를 설치합니다.





3. 프로그램 구현(C#)



아래에 소스 코드를 베타 붙여 둡니다. HTTP 리퀘스트, 응답의 곳은 메소드명을 보면, 무엇을 하고 있는지는 어쩐지 알 수 있다고 생각합니다.

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace RestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            var httpRequest = WebRequest.Create(args[0]);
            httpRequest.ContentType = "application/json";
            httpRequest.Method = "GET";

            var httpResponse = httpRequest.GetResponse();
            using (httpResponse)
            {
                using (var resStream = httpResponse.GetResponseStream())
                {
                    var serializer = new DataContractJsonSerializer(typeof(Product));
                    var info = (Product)serializer.ReadObject(resStream);
                    Console.WriteLine("id: {0} name: {1} category: {2} price: {3}",
                        info.Id, info.Name, info.Category, info.Price);
                }
            }
        }
    }

    [DataContract]
    internal class Product
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Category { get; set; }
        [DataMember]
        public decimal Price { get; set; }
    }
}

주의점으로서는, 서비스측과의 인터페이스가 되는 클래스 (Product )나 그 프로퍼티의 이름 필요하다는 것입니다. 대문자/소문자의 차이도 NG입니다.

소스 코드를 작성한 후 빌드합니다.

4. 동작 확인



실행 결과
>RestClient.exe http://localhost:51585/api/products/1
id: 1 name: Tomato Soup category: Groceries price: 1.0

축하합니다.

5. 배열이 반환되면



그런데 배열이 반환되면 어떻게 할까요?
코드에서 IdName로 수정하기 만하면됩니다.

Program.cs
using (var resStream = httpResponse.GetResponseStream())
{
    //var serializer = new DataContractJsonSerializer(typeof(Product));
    //var info = (Product)serializer.ReadObject(resStream);
    //Console.WriteLine("id: {0} name: {1} category: {2} price: {3}", info.Id, info.Name, info.Category, info.Price);
    var serializer = new DataContractJsonSerializer(typeof(Product[]));
    var info = (Product[])serializer.ReadObject(resStream);
    info.ToList().ForEach( x => Console.WriteLine("id: {0} name: {1} category: {2} price: {3}",
        x.Id, x.Name, x.Category, x.Price));
}

그렇게 할 수있었습니다.

실행 결과
>RestClient.exe http://localhost:51585/api/products
id: 1 name: Tomato Soup category: Groceries price: 1.0
id: 2 name: Yo-yo category: Toys price: 3.75
id: 3 name: Hammer category: Hardware price: 16.99

6. 프록시 서버 자격 증명 설정



요청을 던지기 전에 다음 문장을 추가합니다.

Program.cs
WebRequest.DefaultWebProxy.Credentials = new NetworkCredential("UserName", "Password");

감사의 말



HTTP 액세스나 JSON 해석의 방법에 대해서는, 이쪽의 기사를 참고로 했습니다.
  • argius note / C #에서 HTTP를 통해 JSON을 검색하여 값 검색

  • 「6.프록시 서버의 자격 정보를 설정한다」는, 이쪽의 기사를 참고로 했습니다.
  • 프록시 환경에서 웹 API 호출
  • 좋은 웹페이지 즐겨찾기