RestClient 라이브러리는 REST 서비스를 사용하기 위한 간단한 커넥터를 제공합니다.
프로젝트에서 사용하려면 Mafe.RestClient NuGet 패키지를 프로젝트에 추가하세요.
RestClient의 목표는 개발자가 정말 쉬운 방법으로 모든 서버에 쉽게 연결할 수 있도록 하는 것입니다. 데이터 전송 객체(Dto)를 정의하고 클라이언트를 가지고 놀아보세요!
Build() 메서드를 사용하여 Rest에서 RestBuilder를 만듭니다.
var rest = Rest . Build ( ) ;간단한 get 호출을 생성하려면 다음과 같이 하십시오.
var rest = Rest . Build ( ) ;
var result = rest . Url ( "[URL]" ) . Get ( ) ;또는 GetAsync() 메서드를 사용할 수 있습니다.
var rest = Rest . Build ( ) ;
var result = await rest . Url ( "[URL]" ) . GetAsync ( ) ;이 문서에서 "[URL]"이라는 단어를 찾을 때마다 이는 webAPI의 기본 URL 정의를 나타냅니다.
Root() 끝점을 정의하고 이를 사용하여 요청을 작성할 수 있습니다.
public RestBuilder Root ( ) => rest . Url ( "https://mywebapi.mydomain.com" ) ;그런 다음 다음과 같이 사용할 수 있습니다.
public RestBuilder Root ( ) => Rest . Build ( ) . Url ( "https://mywebapi.mydomain.com" ) ;
var result = Root ( )
. Command ( "/my-action" )
. Payload ( "mystring" )
. Post ( ) ;RestProperties를 사용하여 휴식 루트 지점을 구성합니다. 다음과 같이 간단한 구성을 생성하려면:
RestProperties properties = new RestProperties
{
EndPoint = new Uri ( "[URL]" ) , //if you use .Url("[URL]") you override it
BufferSize = 4096 ,
CertificateOption = ClientCertificateOption . Manual ,
Timeout = TimeSpan . FromMinutes ( 2 )
} ;속성과 함께 Build() 메서드를 사용하여 Rest에서 RestBuilder를 만듭니다.
var rest = Rest . Build ( properties ) ;중간자 공격에 취약하지 않은 안전한 SSL/TLS 세션을 생성하려면 X.509 인증서 검증이 필수적입니다.
인증서 체인 유효성 검사에는 다음 단계가 포함됩니다.
사용자 지정 인증서 체인 유효성 검사를 구현하여 바퀴를 재발명하는 것은 권장되지 않습니다.
TLS 라이브러리는 사용해야 하는 내장 인증서 검증 기능을 제공합니다.
List < string > validCerts = new List < string > ( ) {
"CERT STRING"
} ;
var result = Rest . Build ( )
. CertificateValidation ( ( sender , certificate , chain , errors ) =>
{
// for development, trust all certificates
if ( development ) return true ;
// Compliant: trust only some certificates
return errors == SslPolicyErrors . None
&& validCerts . Contains ( certificate . GetCertHashString ( ) ) ;
} )
. Url ( "[URL]" )
. Get ( ) ;HTTP/1.1 [RFC2617]에 정의된 대로 애플리케이션은 Authorization 요청 헤더에 직접 access_token을 보내야 합니다. HTTP 요청 본문에 Bearer 토큰의 access_token 값을 'Authorization: Bearer {access_token_value}'로 포함하면 됩니다.
인증된 사용자에게 만료된 전달자 토큰의 access_token 또는 새로 고침 토큰이 있는 경우 '401 - 승인되지 않음(유효하지 않거나 만료된 새로 고침 토큰)' 오류가 반환됩니다.
var result = Rest . Build ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. Url ( "[URL]" )
. Get ( ) ;활성 access_token 또는 Refresh_token 속성이 있는 유효한 전달자 토큰은 사용자가 자격 증명을 자주 다시 입력하지 않고도 사용자 인증을 유지합니다. access_token은 활성화된 동안(로그인 또는 갱신 후 최대 1시간) 동안 사용할 수 있습니다. Refresh_token은 336시간(14일) 동안 활성화됩니다. access_token이 만료된 후 다음 예와 같이 활성 새로고침_토큰을 사용하여 새 access_token / 새로고침_토큰 쌍을 얻을 수 있습니다. 이 주기는 최대 90일 동안 지속될 수 있으며 그 이후에는 사용자가 다시 로그인해야 합니다. Refresh_token이 만료되면 토큰을 갱신할 수 없으며 사용자는 다시 로그인해야 합니다.
토큰을 새로 고치려면 "RefreshTokenInvoke"를 자동으로 사용하세요.
var url = "[URL]" ;
var result = Rest . Build ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. RefreshToken ( true )
. RefreshTokenInvoke ( async ( ) =>
{
var result = await rest
. Url ( url )
. Command ( "/refresh" )
. GetAsync < TokenObjectResponse > ( ) ;
doSomethings ( ) ; //store the token inside your env.
return result ;
} )
. Command ( "/detail" )
. Url ( url )
. Get ( ) ;Refresh_token을 취소해야 합니다.
NetworkCredential 클래스는 기본, 다이제스트, NTLM 및 Kerberos와 같은 암호 기반 인증 체계에 자격 증명을 제공하는 기본 클래스입니다. CredentialCache 클래스와 같이 ICredentials 인터페이스를 구현하는 클래스는 NetworkCredential 개체를 반환합니다. 이 클래스는 SSL(Secure Sockets Layer) 클라이언트 인증과 같은 공개 키 기반 인증 방법을 지원하지 않습니다.
var result = Rest . Build ( )
. NetworkCredential ( "myUsername" , "myPassword" )
. Url ( "[URL]" )
. Get ( ) ; var result = rest
. NetworkCredential ( ( ) => new System . Net . NetworkCredential ( "myUsername" , "myPassword" ) )
. Url ( "[URL]" )
. Get ( ) ;Headers 컬렉션에는 요청과 관련된 프로토콜 헤더가 포함되어 있습니다. Header((h)=>{}) 메서드를 사용하면 키 목록을 추가할 수 있습니다.
var result = Rest . Build ( )
. Header ( ( h ) => {
if ( ! h . Contains ( "auth-custom" ) )
h . Add ( "auth-custom" , "value" ) ;
} )
. Url ( "[URL]" )
. Get ( ) ;RestClient에서는 두 가지 유형의 직렬화, 즉 Xml과 Json을 지원하지만 ISerializerContent를 구현하여 직렬화를 사용자 지정할 수도 있습니다. RestClient는 .Json()을 사용하여 객체를 json으로 직렬화합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( )
. Get < ResponseObject > ( ) ;다음과 같이 json 직렬 변환기 옵션을 .Json() 메서드에 전달할 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( new JsonSerializerOptions {
WriteIndented = true
} )
. Get < ResponseObject > ( ) ;위의 코드 조각은 System.Text.Json 라이브러리 사용을 고려합니다. Netwnsoft를 다음과 같이 사용한다면:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( new JsonSerializerSettings {
Formatting = Formatting . Indented
} )
. Get < ResponseObject > ( ) ;RestClient는 .Xml()을 사용하여 객체를 xml로 직렬화합니다.
var result = rest
. Url ( "[URL]" )
. Xml ( )
. Get < ResponseObject > ( ) ;다음과 같이 설정을 .Xml() 메서드에 전달할 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Xml ( new XmlReaderSettings { Indent = true } , new XmlWriterSettings { IgnoreWhitespace = true } )
. Get < ResponseObject > ( ) ;ISerializerContent 인터페이스를 구현하여 사용자 지정 직렬화를 수행하는 방법에 대한 예는 다음과 같습니다.
public class MyCustomSerializer : ISerializerContent
{
public string MediaTypeAsString => throw new NotImplementedException ( ) ;
public object DeserializeObject ( string value , Type typeOf , object options = null )
{
throw new NotImplementedException ( ) ;
}
public string SerializeObject ( object value , Type typeOf , object options = null )
{
throw new NotImplementedException ( ) ;
}
}이제 다음과 같이 MyCustomSerializer를 사용할 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. CustomSerializer ( new MyCustomSerializer { } )
. Get < ResponseObject > ( ) ;BufferSize는 업로드 및 다운로드 스트림 중에 버퍼 크기를 설정하는 데 사용할 수 있습니다. 기본값은 80Kb입니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. BufferSize ( 4096 * 5 * 5 ) //100Kb
. Get ( ) ;지정된 리소스와 통신하는 동안 gzip 압축을 활성화합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. EnableGZipCompression ( )
. Get ( ) ;라이브러리는 응답을 자동으로 압축 해제합니다.
GET은 가장 일반적인 HTTP 방법 중 하나이며 GET은 지정된 리소스에서 데이터를 요청하는 데 사용됩니다.
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Get ( ) ;
var result = await rest
. Url ( "[URL]" )
. GetAsync ( ) ;GET 요청에 대한 기타 참고 사항:
쿼리 문자열(이름/값 쌍)은 GET 요청의 URL로 전송됩니다.
어떤 경우에는 인수를 쿼리 문자열로 사용해야 합니다. Parameter(key, value) 메소드를 사용하여 다음과 같이 해결할 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/path" )
. Parameter ( "id" , "10" )
. Parameter ( "type" , "myType" )
. Get ( ) ;생성된 URL은 다음과 같습니다: [URL]/path?id=10&type=myType
POST는 리소스 생성/업데이트를 위해 서버에 데이터를 보내는 데 사용됩니다. POST를 통해 서버로 전송된 데이터는 HTTP 요청의 요청 페이로드에 저장됩니다.
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. Post < ResponseObject > ( ) ;
var result = await rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. PostAsync < ResponseObject > ( ) ;Post는 다음과 같은 용도로 사용되는 또 다른 일반적인 http 방법입니다.
PUT은 리소스 생성/업데이트를 위해 서버에 데이터를 보내는 데 사용됩니다.
POST와 PUT의 차이점은 PUT 요청이 멱등원이라는 점입니다. 즉, 동일한 PUT 요청을 여러 번 호출하면 항상 동일한 결과가 생성됩니다. 반면에 POST 요청을 반복적으로 호출하면 동일한 리소스를 여러 번 생성하는 부작용이 있습니다.
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. Put < ResponseObject > ( ) ;
var result = await rest
. Url ( "[URL]" )
. Payload ( new Object { } )
. PutAsync < ResponseObject > ( ) ;DELETE 메소드는 지정된 리소스를 삭제합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. Delete < ResponseObject > ( ) ;
var result = await Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. DeleteAsync < ResponseObject > ( ) ;DOWNLOAD 메소드는 지정된 리소스를 다운로드합니다.
var result = Rest . Build ( )
. Download ( "[URL]" ) ;
var result = await rest
. DownloadAsync ( "[URL]" ) ;OnDownloadProgress를 사용하여 다운로드 상태를 표시할 수 있습니다.
var rest = Rest . Build ( ) ;
var result = await rest
. OnDownloadProgress ( ( d ) => Console . WriteLine ( $ " { d . CurrentBytes } / { d . TotalBytes } " ) )
. DownloadAsync ( "[URL]" ) ;작업을 취소해야 한다는 알림을 전파합니다.
CancellationToken을 사용하면 스레드, 스레드 풀 작업 항목 또는 Task 개체 간의 협력 취소가 가능합니다. CancellationTokenSource에서 검색된 취소 토큰을 관리하는 CancellationTokenSource 개체를 인스턴스화하여 취소 토큰을 만듭니다.
다음 예에서는 취소 토큰을 사용하여 실행을 중지합니다.
// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource ( ) ;
CancellationToken token = source . Token ;
// Schedules a cancel operation on this System.Threading.CancellationTokenSource
// after the specified number of milliseconds
token . CancelAfter ( 3000 ) ;
var file1 = Rest . Build ( ) . DownloadAsync ( "[URL FILE1]" , token . Token ) ;
var file2 = Rest . Build ( ) . DownloadAsync ( "[URL FILE2]" , token . Token ) ;
var get1 = Rest . Build ( ) . Url ( "[URL GET1]" ) . GetAsync < MyObject > ( token . Token ) ;
Task . WaitAll ( file1 , file2 , get1 ) ;취소를 요청하면 TaskCancellatedException이 발생합니다. 예외는 RestResult 객체로 캡슐화됩니다.
지정된 리소스를 맞춤설정하는 CUSTOM 메서드입니다.
HttpMethod PATCH = new HttpMethod ( "PATCH" ) ;
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. CustomCall < ResponseObject > ( PATCH ) ;
var result = await rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. CustomCallAsync < ResponseObject > ( PATCH ) ;RestClient는 Playload(obj) 메소드를 사용하여 요청 시 객체를 설정합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new RequestObject { } )
. Post < ResponseObject > ( ) ; var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new RequestObject { } )
. Put < ResponseObject > ( ) ;필요한 경우 요청을 양식 URL 인코딩으로 사용할 수 있습니다. 이를 사용하려면 다음과 같이 활성화해야 합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. EnableFormUrlEncoded ( true )그런 다음 매개변수를 사전으로 전달할 수 있습니다.
var params = new Dictionary < string , string > ( ) ;
params . Add ( "key1" , "value1" ) ;
params . Add ( "key2" , "value2" ) ;
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. EnableFormUrlEncoded ( true )
. FormUrlEncoded ( params )
. Post ( ) ;핸들러 내부에 매개변수를 전달하고 form-url-encoded를 활성화할 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. FormUrlEncoded ( true , ( p ) =>
{
p . Add ( "key1" , "value1" ) ;
p . Add ( "key2" , "value2" ) ;
} )
. Post ( ) ;OnUploadProgress는 요청이 실행 중이고 데이터가 나갈 때 발생합니다. 다음과 같이 업로드되는 데이터의 비율을 얻을 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnUploadProgress ( p =>
{
DoSomethings ( p . ProgressPercentage ) ;
} ) //occurs during request
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;OnDownloadProgress는 응답이 실행 중이고 데이터가 들어올 때 발생합니다. 다음과 같이 다운로드되는 데이터의 백분율을 얻을 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnDownloadProgress ( p =>
{
DoSomethings ( p . ProgressPercentage ) ;
} ) //occurs during response
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;기본값은 100,000밀리초(100초)입니다. 무한 시간 초과를 설정하려면 속성 값을 InfiniteTimeSpan으로 설정합니다. DNS(Domain Name System) 쿼리가 반환되거나 시간 초과되는 데 최대 15초가 걸릴 수 있습니다. 요청에 확인이 필요한 호스트 이름이 포함되어 있고 제한 시간을 15초 미만의 값으로 설정한 경우 요청에 대한 제한 시간을 나타내기 위해 예외가 발생하기까지 15초 이상이 걸릴 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Timeout ( 3200 ) //milliseconds
. Get < ResponseObject > ( ) ; var result = Rest . Build ( )
. Url ( "[URL]" )
. Timeout ( TimeSpan . FromMinutes ( 10 ) )
. Get < ResponseObject > ( ) ;OnStart는 요청이 시작될 때 트리거되는 이벤트입니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnStart ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;OnPreviewContentRequestAsString은 요청이 준비되었지만 아직 전송되지 않았을 때 트리거되는 이벤트입니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreviewContentRequestAsString ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;OnPreviewContentResponseAsString은 응답이 수신되고 아직 역직렬화되지 않은 경우 트리거되는 이벤트입니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreviewContentResponseAsString ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;OnPreResult는 요청이 완료되고 있지만 아직 완료되지 않은 경우에 발생합니다. OnPreResult가 발생하면 요청 결과를 가져와 사용하는 등의 작업을 수행할 수 있습니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreCompleted ( ( r ) => {
DoSomethings ( r . Result ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;OnException은 요청에서 예외가 발생할 때 발생합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnException ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;OnCompleted는 요청이 완료되면 발생합니다.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnCompleted ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;RestClient를 사용하면 유연하고 강력한 네트워크 계층을 만들 수 있으며 사용이 매우 쉽습니다. 아래에서 전체 코드 데모와 전체 코드 예제를 찾을 수 있습니다.
public class NetworkService {
//building context
public RestBuilder Root ( )
=> Rest . Build ( )
. CertificateValidation ( ( sender , certificate , chain , errors ) =>
{
if ( development ) return true ;
return errors == SslPolicyErrors . None
&& validCerts . Contains ( certificate . GetCertHashString ( ) ) ;
} )
. Url ( "[URL]" ) ;
public RestBuilder RootAuthentication ( )
=> Root ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. RefreshToken ( )
. RefreshTokenInvoke ( async ( ) => await PostRefreshAsync ( new RefreshRequest { } ) ) ;
public RestBuilder UsersRoot ( )
=> Root ( ) . Command ( "/Users" ) ;
public RestBuilder DimensionsRoot ( )
=> Root ( ) . Command ( "/Dimensions" ) ;
public RestBuilder EventsRoot ( )
=> RootAuthentication ( ) . Command ( "/Events" ) ;
//requests
public async Task < RestResult < LoginResponse > > PostLoginAsync ( LoginRequest request )
=> await UsersRoot ( )
. Command ( "/Login" ) //[URL]/Users/Login
. Payload ( request )
. PostAsync < LoginResponse > ( ) ;
public async Task < RestResult < RuleResponse > > GetRulesAsync ( )
=> await UsersRoot ( )
. Command ( "/Rules" )
. GetAsync < RuleResponse > ( ) ;
public async Task < RestResult < RefreshResponse > > PostRefreshAsync ( RefreshRequest request )
=> await UsersRoot ( )
. Command ( "/Refresh" )
. Payload ( request )
. PostAsync < RefreshResponse > ( ) ;
public async Task < RestResult < CountryResponse > > PostCountriesAsync ( CountryRequest request )
=> await DimensionsRoot ( )
. Command ( "/Countries" )
. Payload ( request )
. PostAsync < CountryResponse > ( ) ;
public async Task < RestResult < EventDetailResponse > > PostEventDetailAsync ( EventDetailRequest request )
=> await EventsRoot ( )
. Command ( "/EventDetail" )
. Payload ( request )
. PostAsync < EventDetailResponse > ( ) ;
}