반응형

github에는 작성해놓았는데 블로그에는 이것조차 없네요. 머쓱

 

20241217 - 불필요부분을 뺀다고 뺐는데도 작성길이가 길어 현재 본문에서는

라이브러리 사용시 알아야할 내용과 Get방식만 설명드립니다.

 

 

참고로 .NET Standard 6.0 부터 사용해보았기 때문에

이전 버전은 다르던데 어떻게하는거냐라고 물으신다면 저도 모를꺼예요.

특히 System.Net.Http.Json는 Newtonsoft.Json이 .NET Standard에 와서 System.Text.Json으로 내장되면서 생긴 것으로 알고 있어서, 이전 버전에 없을 확률이 높습니다.

 

 

 

HTTP기초를 먼저 작성하면 좋았을텐데,,, 이 것 부터 쓰게 되네요.

우선 다른데서 공부하고 오셨다는 전제하에 작성해보겠습니다.

 

 

System.Net.Http / System.Net.Http.Json 라이브러리를 사용하기위해 근간에 되는 HttpClient의 인스턴스를 선언합니다.

예제에서는 단순하게 선언하겠습니다.

 

참고로 실제 서버나 프로그램에서 사용하시게되면 httpClientFactory에 넣어서 CreateClient로 가져오시면 매번 선언하지 않고 자원을 아끼면서 적절하게 사용하실 수 있을텐데요. 

 

여기서는 호출방법 자체에 포인트를 맞추고 있어 따로 다루지 않습니다.

(위 내용도 궁금하신 분들은 IHttpClientFactory 인터페이스를 참조하세요.)

 

HttpClient httpClient = new(){
    // 기본 URL 설정
    BaseAddress = new Uri("https://api.example.com/"),

    // 타임아웃 설정 (예: 30초)
    Timeout = TimeSpan.FromSeconds(30)
};

 

 HTTP 메소드에 따라 의 용법도 조금씩 다릅니다.

 

HTTP 헤더 입력값
httpClient.DefaultRequestHeaders.Add("Key", "Value");

위와 같은 형태로 헤더를 입력합니다. 영어를 보시면 Default Request Headers에서 감이 오시는 분이 있을까요?

이렇게 헤더를 추가하게 되면, 같은 인스턴스의 httpClient를 호출할때 항상 헤더값에 입력되게 됩니다.

 

따라서 하나의 httpClient 인스턴스를 돌려쓰시면서, 헤더값을 다르게 해야한다면,

아래의 첫문단과 같이 Clear를 해줍니다.

 

항상 같게 해줘야한다면 아래의 if문과 같이 추가해주는 것이 안정적인 방법일 것입니다.

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Clear();

if (!httpClient.DefaultRequestHeaders.Contains("Key"))
    httpClient.DefaultRequestHeaders.Add("Key", "Value");

 

GET 방식

본문 상단에서 httpClient를 선언할때 baseAddress를 적어주었기 때문에 호출할때는 뒷부분(endpoint)만 작성하면 됩니다.

 

.NET Standard에 오기전 구 버전에서는 HttpRequestMessage로 작성하여 이것저것 넣어줘야 했다면, 비동기 방식의 System.Net.Http 메소드는 사용이 아주 간편합니다.

string endpoint = "/class/students"
HttpResponseMessage response = await httpClient.GetAsync(endpoint);

 

요청이 성공했는지 보는 방법은 단순합니다.

response.StatusCode에 HTTP status code가 반환됩니다.

 

 

System.Net.Http에서 제공하는 enum type의 HttpStatusCode 중 일부를 정리해보았습니다.
HttpStatusCode.{아래 알파벳}으로 사용하시면 되겠습니다.

다만 목록의 코드별 내용을 자세히 설명하기에는 너무 길어 예제에서 사용하는 것들 정도만 언급드리겠습니다.


ex) if (response.StatusCode ==HttpStatusCode.OK)
또는 if (response.StatusCode == 200)

200번대
OK = 200, Created = 201,  Accepted = 202, NoContent = 204, ResetContent = 205
   
300번대
Ambiguous = 300, Moved = 301, Found = 302, Redirect = 302, RedirectMethod = 303,  Unused = 306,        TemporaryRedirect = 307, PermanentRedirect = 308

400번대
BadRequest = 400, Unauthorized = 401, Forbidden = 403, NotFound = 404, MethodNotAllowed = 405,        NotAcceptable = 406, RequestTimeout = 408, RequestEntityTooLarge = 413, RequestUriTooLong = 414,        UnsupportedMediaType = 415,      

500번대
InternalServerError = 500, NotImplemented = 501, BadGateway = 502, ServiceUnavailable = 503,        GatewayTimeout = 504,

 

Get 방식의 http method는 정보의 조회 등인 경우가 많아 대부분 200번 즉 response.StatusCode 가 HttpStatusCode.OK일 거예요. 다만, 구체적으로 반환되는 HTTP Status Code는 API를 제작한 개발사/개발자에 문의 또는 설명문서를 참조하여 정하시는 것이 좋겠습니다.

 

다만, 200번대가 보통 성공을 나타낸다고 약속되어져 있습니다. (제가 약속한거 아닙니다.)

따라서 다음과 같은 방법으로 200번대면 성공이라고 가정, 아니면 실패를 예외를 던지는 속성과 함수도 존재합니다.

// response.IsSuccessStatusCode: response가 200번 대면 true를 반환하는 bool값

if(response.IsSuccessStatusCode) {
// 성공
}



// if문도 필요 없이 200번대면 다음 레코드를 읽고, 200번대가  아니면 예외를 던지는 함수
response.EnsureSuccessStatusCode();

 

응답이 성공했으면 원하는 응답을 읽어와야하고, 그 방법에는 여러가지가 있을텐데요. 두가지를 설명드리겠습니다.

 

1. 응답을 모두 string으로 받아오는 방법

c#의 함수나 속성명은 상당히 직관적입니다.

[응답][내용][문자열]으로 불러오겠습니다.

(response)(content)(string)

var responseContent = await response.Content.ReadAsStringAsync();

 

 

그런데 대부분은 string 자체를 사용하진 않을 것입니다. 약속된 API라면 반환값이 json형태의 문자열이기 때문이죠.

따라서 json형태의 문자열을 다음과 같이 클래스로 바꿔줍니다.( System.Text.Json 필요)

var result =  JsonSerializer.Deserialize<ResultClass>(responseContent, new JsonSerializerOptions());

 

JsonSerializerOptions 옵션 등과 같은 System.Text.Json의 고유 기능은 제가 자세히 설명해놓은 글

(링크:  https://pichen.tistory.com/52 ) 을 참조하시기 바랍니다.

 

[.NET 라이브러리] System.Text.Json

안녕하세요. 예전에 NewtonSoft.Json 라이브러리를 설명드렸었는데요. 이번엔 System안에 속한 Json 컨버팅 라이브러리를 설명드리도록 하겠습니다. NewtonSoft.Json( [c# dotnet nuget] Newtonsoft.Json (tistory.com) )

pichen.tistory.com

저의 경우 NewtonSoft.Json은 .Net Framework에서는 많이 사용했지만. Net Standard에 와서는 내장된 System.Text.Json을 적극 사용하고 있습니다. 특히 아래 2번 방법과 JsonSerializerOptions 을 공유하고 있기 때문에 사용하시는 것을 권장드립니다.

 

 

 

2. 응답내용을 불러올때 클래스로 만드는 방법입니다. (using System.Net.Http.Json 필요)

ResultClass result = await response.Content.ReadFromJsonAsync<ResultClass>();

저는 보통 클라이언트 호출부를 함수로 만들어

return await response.Content.ReadFromJsonAsync<ResultClass>();

형태로 사용하거나 var로 선언하긴하지만, 여러분에게 명시적으로 보여드리기 위해 클래스로 선언부를 작성하였습니다.

개발 초기에는 응답내용을 전부 로그를 찍기 위해 1번으로 시작할때도 있지만, 주로 2번을 사용하고 있습니다.

ReadFromJsonAsync의 정의를 보면, System.Text.Json의 JsonSerializerOptions 옵션을 공유합니다.

null처리, 기본값 처리 등을 손쉽게 할 수 있고, 그에 따라 api의 상세한 요구조건을 컨트롤 할 수 있으니 반드시 알아두시면 좋겠습니다.

 

ResultClass가 무엇인가요? 라고 물으실 수 있을 것 같아요. 아무렇게나 작성한 임의의 클래스입니다.

{"number": 1} 이라는 형태의 json이 왔고 약속된 형태라면,

ResultClass은 아래와 같이 정의가 되었을 것입니다.

class ResultClass{

	public int Number {get; set;}

}

// 또는

class ResultClass{

	[JsonPropertyName("number")]
	public int Sequence {get; set;}
    
}

 

serialize했을때 json이 되는 클래스를 만들었다라고 보시면 되겠습니다.

이 포스트는 json, json과 클래스의 관계에 대한 설명글이 아니기 때문에 이 정도만 작성하도록하고, 여태까지 설명 내용을 한 번에 보실 수 있도록 담아보겠습니다.

 

// json문자열을 역직렬화할 Model 클래스
class ResultClass{

	[JsonPropertyName("number")]
	public int Sequence {get; set;}
    
}


// HttpClient 선언
HttpClient httpClient = new(){
    BaseAddress = new Uri("https://api.example.com/"),
    Timeout = TimeSpan.FromSeconds(30)	// 굳이 적지 않아도 되나 기본값이 30초
};

// 필요시 헤더 추가
if (!httpClient.DefaultRequestHeaders.Contains("Key"))
    httpClient.DefaultRequestHeaders.Add("Key", "Value");

// Get 방식 호출
HttpResponseMessage response = await httpClient.GetAsync("/class/students");

// 성공 여부 검증
response.EnsureSuccessStatusCode();

// 성공시 json을 역직렬화하여 변수에 담는다.
var result = await response.Content.ReadFromJsonAsync<ResultClass>();
반응형

+ Recent posts