Pustaka RestClient menyediakan konektor sederhana untuk menggunakan layanan REST.
Untuk menggunakannya dalam proyek Anda, tambahkan paket Mafe.RestClient NuGet ke proyek Anda.
Tujuan dari RestClient adalah untuk memungkinkan pengembang terhubung dengan mudah ke server mana pun dengan cara yang sangat mudah. Cukup tentukan Objek Transfer Data (Dto) Anda dan mulailah bermain dengan klien!
Gunakan metode Build() untuk membuat RestBuilder dari Rest:
var rest = Rest . Build ( ) ;
Untuk membuat panggilan get sederhana, lakukan saja seperti ini:
var rest = Rest . Build ( ) ;
var result = rest . Url ( "[URL]" ) . Get ( ) ;
atau kita bisa menggunakan metode GetAsync():
var rest = Rest . Build ( ) ;
var result = await rest . Url ( "[URL]" ) . GetAsync ( ) ;
Setiap kali Anda menemukan kata "[URL]" dalam dokumen ini, kata tersebut mengacu pada definisi URL dasar webAPI.
Kita dapat mendefinisikan titik akhir Root() dan menggunakannya untuk membuat permintaan.
public RestBuilder Root ( ) => rest . Url ( "https://mywebapi.mydomain.com" ) ;
dan kemudian, kita bisa menggunakannya, seperti ini:
public RestBuilder Root ( ) => Rest . Build ( ) . Url ( "https://mywebapi.mydomain.com" ) ;
var result = Root ( )
. Command ( "/my-action" )
. Payload ( "mystring" )
. Post ( ) ;
Untuk menggunakan RestProperties untuk mengonfigurasi titik akar istirahat Anda. Untuk membuat konfigurasi sederhananya seperti ini:
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 )
} ;
Gunakan metode Build() dengan properti untuk membuat RestBuilder dari Rest:
var rest = Rest . Build ( properties ) ;
Validasi sertifikat X.509 sangat penting untuk menciptakan sesi SSL/TLS yang aman dan tidak rentan terhadap serangan man-in-the-middle.
Validasi rantai sertifikat mencakup langkah-langkah berikut:
Tidak disarankan untuk menemukan kembali roda dengan menerapkan validasi rantai sertifikat khusus.
Pustaka TLS menyediakan fungsi validasi sertifikat bawaan yang harus digunakan.
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 ( ) ;
Seperti yang didefinisikan oleh HTTP/1.1 [RFC2617], aplikasi harus mengirimkan access_token langsung di header permintaan Otorisasi. Anda dapat melakukannya dengan memasukkan nilai access_token token pembawa di isi permintaan HTTP sebagai 'Otorisasi: Pembawa {access_token_value}'.
Jika pengguna yang diautentikasi memiliki access_token atau refresh_token token pembawa yang kedaluwarsa, maka kesalahan '401 - Tidak sah (token penyegaran tidak valid atau kedaluwarsa)' akan dikembalikan.
var result = Rest . Build ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. Url ( "[URL]" )
. Get ( ) ;
Token pembawa yang valid (dengan properti access_token atau refresh_token aktif) menjaga autentikasi pengguna tetap hidup tanpa mengharuskan pengguna untuk sering memasukkan kembali kredensial mereka. Access_token dapat digunakan selama masih aktif yaitu maksimal satu jam setelah login atau perpanjangan. refresh_token aktif selama 336 jam (14 hari). Setelah access_token habis masa berlakunya, refresh_token yang aktif dapat digunakan untuk mendapatkan pasangan access_token / refresh_token baru seperti yang ditunjukkan pada contoh berikut. Siklus ini dapat berlanjut hingga 90 hari setelah itu pengguna harus login kembali. Jika refresh_token habis masa berlakunya, token tidak dapat diperpanjang dan pengguna harus login kembali.
Untuk menyegarkan token, gunakan "RefreshTokenInvoke" secara otomatis.
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 harus dicabut:
Kelas NetworkCredential adalah kelas dasar yang menyediakan kredensial dalam skema otentikasi berbasis kata sandi seperti basic, digest, NTLM, dan Kerberos. Kelas yang mengimplementasikan antarmuka ICredentials, seperti kelas CredentialCache, mengembalikan objek NetworkCredential. Kelas ini tidak mendukung metode autentikasi berbasis kunci publik seperti autentikasi klien Secure Sockets Layer (SSL).
var result = Rest . Build ( )
. NetworkCredential ( "myUsername" , "myPassword" )
. Url ( "[URL]" )
. Get ( ) ;
var result = rest
. NetworkCredential ( ( ) => new System . Net . NetworkCredential ( "myUsername" , "myPassword" ) )
. Url ( "[URL]" )
. Get ( ) ;
Koleksi Header berisi header protokol yang terkait dengan permintaan. Metode Header((h)=>{}) memungkinkan Anda menambahkan daftar kunci.
var result = Rest . Build ( )
. Header ( ( h ) => {
if ( ! h . Contains ( "auth-custom" ) )
h . Add ( "auth-custom" , "value" ) ;
} )
. Url ( "[URL]" )
. Get ( ) ;
Dua jenis serialisasi didukung oleh RestClient: Xml dan Json, tetapi ISerializerContent dapat diimplementasikan untuk menyesuaikan serialisasi. RestClient menggunakan .Json() untuk membuat serial objek menjadi json.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( )
. Get < ResponseObject > ( ) ;
Dimungkinkan untuk meneruskan opsi json serializer ke metode .Json(), seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( new JsonSerializerOptions {
WriteIndented = true
} )
. Get < ResponseObject > ( ) ;
Kode cuplikan di atas mempertimbangkan penggunaan perpustakaan System.Text.Json. Jika kita menggunakan Netwnsoft seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( new JsonSerializerSettings {
Formatting = Formatting . Indented
} )
. Get < ResponseObject > ( ) ;
RestClient menggunakan .Xml() untuk membuat serial objek menjadi xml.
var result = rest
. Url ( "[URL]" )
. Xml ( )
. Get < ResponseObject > ( ) ;
Dimungkinkan untuk meneruskan pengaturan ke metode .Xml(), seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Xml ( new XmlReaderSettings { Indent = true } , new XmlWriterSettings { IgnoreWhitespace = true } )
. Get < ResponseObject > ( ) ;
Di bawah ini contoh bagaimana Anda dapat melakukan Serialisasi khusus dengan mengimplementasikan antarmuka 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 ( ) ;
}
}
Sekarang, kita bisa menggunakan MyCustomSerializer seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. CustomSerializer ( new MyCustomSerializer { } )
. Get < ResponseObject > ( ) ;
BufferSize dapat digunakan untuk mengatur ukuran buffer selama streaming upload dan download. Nilai defaultnya adalah 80Kb
var result = Rest . Build ( )
. Url ( "[URL]" )
. BufferSize ( 4096 * 5 * 5 ) //100Kb
. Get ( ) ;
Mengaktifkan kompresi gzip selama komunikasi dengan sumber daya tertentu:
var result = Rest . Build ( )
. Url ( "[URL]" )
. EnableGZipCompression ( )
. Get ( ) ;
Perpustakaan membuka kompresi respons secara otomatis.
GET adalah salah satu metode HTTP yang paling umum dan GET digunakan untuk meminta data dari sumber daya tertentu
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Get ( ) ;
var result = await rest
. Url ( "[URL]" )
. GetAsync ( ) ;
Beberapa catatan lain tentang permintaan GET:
Perhatikan bahwa string kueri (pasangan nama/nilai) dikirim dalam URL permintaan GET.
Dalam beberapa kasus kita perlu menggunakan argumen sebagai string kueri. Kita dapat menggunakan metode Parameter(key, value) untuk menyelesaikannya seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/path" )
. Parameter ( "id" , "10" )
. Parameter ( "type" , "myType" )
. Get ( ) ;
Url yang dihasilkan adalah: [URL]/path?id=10&type=myType
POST digunakan untuk mengirim data ke server untuk membuat/memperbarui sumber daya. Data yang dikirim ke server dengan POST disimpan dalam muatan permintaan permintaan 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 > ( ) ;
Posting adalah metode http umum lainnya, yang digunakan untuk:
PUT digunakan untuk mengirim data ke server untuk membuat/memperbarui sumber daya.
Perbedaan antara POST dan PUT adalah permintaan PUT bersifat idempoten. Artinya, memanggil permintaan PUT yang sama beberapa kali akan selalu menghasilkan hasil yang sama. Sebaliknya, memanggil permintaan POST berulang kali memiliki efek samping berupa pembuatan sumber daya yang sama beberapa kali.
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 > ( ) ;
Metode DELETE menghapus sumber daya yang ditentukan.
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 > ( ) ;
Metode UNDUH mengunduh sumber daya yang ditentukan.
var result = Rest . Build ( )
. Download ( "[URL]" ) ;
var result = await rest
. DownloadAsync ( "[URL]" ) ;
Apakah mungkin menampilkan status unduhan dengan OnDownloadProgress.
var rest = Rest . Build ( ) ;
var result = await rest
. OnDownloadProgress ( ( d ) => Console . WriteLine ( $ " { d . CurrentBytes } / { d . TotalBytes } " ) )
. DownloadAsync ( "[URL]" ) ;
Menyebarkan pemberitahuan bahwa operasi harus dibatalkan.
CancellationToken memungkinkan pembatalan kooperatif antara thread, item kerja kumpulan thread, atau objek Tugas. Anda membuat token pembatalan dengan membuat instance objek CancellationTokenSource, yang mengelola token pembatalan yang diambil dari CancellationTokenSource-nya.
Contoh berikut menggunakan token pembatalan untuk menghentikan eksekusi:
// 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 ) ;
Setelah permintaan pembatalan, ia memunculkan TaskCancellatedException. Pengecualian akan dienkapsulasi ke dalam objek RestResult.
Metode CUSTOM menyesuaikan sumber daya yang ditentukan.
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 menggunakan metode Playload(obj) untuk menyetel objek berdasarkan permintaan:
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 > ( ) ;
Bila perlu, kita dapat menggunakan permintaan tersebut sebagai formulir-url yang disandikan. Untuk menggunakannya kita perlu mengaktifkannya, seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. EnableFormUrlEncoded ( true )
dan kemudian kita dapat meneruskan parameter sebagai kamus:
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 ( ) ;
Dimungkinkan untuk meneruskan parameter di dalam handler dan mengaktifkan form-url-encoded:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. FormUrlEncoded ( true , ( p ) =>
{
p . Add ( "key1" , "value1" ) ;
p . Add ( "key2" , "value2" ) ;
} )
. Post ( ) ;
OnUploadProgress terjadi ketika permintaan sedang berjalan dan data keluar. Kita bisa mendapatkan persentase data yang diunggah seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnUploadProgress ( p =>
{
DoSomethings ( p . ProgressPercentage ) ;
} ) //occurs during request
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnDownloadProgress terjadi ketika respon berjalan dan data masuk. Kita bisa mendapatkan persentase data yang diunduh seperti ini:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnDownloadProgress ( p =>
{
DoSomethings ( p . ProgressPercentage ) ;
} ) //occurs during response
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
Nilai defaultnya adalah 100.000 milidetik (100 detik). Untuk menyetel batas waktu tak terbatas, setel nilai properti ke InfiniteTimeSpan. Kueri Sistem Nama Domain (DNS) mungkin memerlukan waktu hingga 15 detik untuk kembali atau habis waktu. Jika permintaan Anda berisi nama host yang memerlukan resolusi dan Anda menyetel Batas Waktu ke nilai kurang dari 15 detik, mungkin diperlukan waktu 15 detik atau lebih sebelum Pengecualian ditampilkan untuk menunjukkan batas waktu permintaan Anda.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Timeout ( 3200 ) //milliseconds
. Get < ResponseObject > ( ) ;
var result = Rest . Build ( )
. Url ( "[URL]" )
. Timeout ( TimeSpan . FromMinutes ( 10 ) )
. Get < ResponseObject > ( ) ;
OnStart adalah peristiwa yang terpicu saat permintaan dimulai.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnStart ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnPreviewContentRequestAsString adalah peristiwa yang terpicu saat permintaan sudah siap dan belum terkirim.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreviewContentRequestAsString ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnPreviewContentResponseAsString adalah peristiwa yang terpicu saat respons diterima dan belum dideserialisasi.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreviewContentResponseAsString ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnPreResult terjadi ketika permintaan sudah selesai tetapi masih belum selesai. Ketika OnPreResult muncul kita dapat melakukan sesuatu, misalnya mengambil dan menggunakan hasil permintaan.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreCompleted ( ( r ) => {
DoSomethings ( r . Result ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnException terjadi ketika permintaan memunculkan pengecualian.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnException ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnCompleted terjadi ketika permintaan selesai.
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnCompleted ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
RestClient memungkinkan untuk membuat lapisan jaringan yang fleksibel dan kuat serta sangat mudah digunakan. Di bawah ini Anda menemukan demo kode lengkap, contoh kode lengkap.
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 > ( ) ;
}