External Api Calls Using Rest Sharp in C
In today's world of Microservices, it is very common to have multiple services that are communicating with each other. In this tutorial we will create a new webapi project and add a service to make external api calls using RestSharp.
Prerequisites
π― .Net installed on your machine
π― Visual Studio Code or Visual Studio
π― Postman or any other tool to make api calls
Project Setup
mkdir RestSharpDemo
cd RestSharpDemo
Create a new sln file
dotnet new sln -n RestSharpDemo
Create a new webapi project
dotnet new webapi -n RestSharpDemo.Api
Add the project to the solution
dotnet sln add **/*.csproj
Add the following nuget packages to the project in the RestSharpDemo.Api folder
cd RestSharpDemo.Api
dotnet add package RestSharp
Create a Services folder in the RestSharpDemo.Api project
mkdir Services
cd Services
Create an interface for the service for the external api
touch IExternalApiService.cs
using RestSharp; // comes from the nuget package
namespace RestSharpDemo.Api.Services
{
public interface IExternalApiService<T> where T : class
{
Task<List<T>> GetAll(string subURL, Dictionary<string, string> queryParams = null!);
Task<T> GetById(Int64 Id, string subURL);
Task<RestResponse> Add(T model, string subURL);
Task<RestResponse> Update(T model, string subURL);
Task<RestResponse> Delete(Int64 Id, string subURL);
}
}
Create a class for the service for the external api
touch ExternalApiService.cs
using RestSharp; // comes from the nuget package
namespace RestSharpDemo.Api.Services
{
public class ExternalApiService<T> : IExternalApiService<T> where T : class
{
private readonly RestClient _client;
private readonly IConfiguration _configuration;
public ExternalApiService(IConfiguration configuration)
{
_configuration = configuration;
_client = new RestClient(_configuration["ExternalApi:BaseUrl"] ?? string.Empty);
}
public async Task<List<T>> GetAll(string subURL, Dictionary<string, string> queryParams = null!)
{
var request = new RestRequest(subURL, Method.Get)
{ RequestFormat = DataFormat.Json };
if (queryParams != null)
{
foreach (var param in queryParams)
{
request.AddQueryParameter(param.Key, param.Value);
}
}
var response = await _client.ExecuteAsync<List<T>>(request);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception($"Error calling external api: {response.ErrorMessage}");
}
return response.Data!;
}
public async Task<T> GetById(Int64 Id, string subURL)
{
var request = new RestRequest($"{subURL}/{Id}", Method.Get)
{ RequestFormat = DataFormat.Json };
var response = await _client.ExecuteAsync<T>(request);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception($"Error calling external api: {response.ErrorMessage}");
}
return response.Data!;
}
public async Task<RestResponse> Add(T model, string subURL)
{
var request = new RestRequest(subURL, Method.Post);
request.AddJsonBody(model);
var response = await _client.ExecuteAsync(request);
//check server not available
if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
{
throw new Exception($"Server not available: {response.ErrorMessage}");
}
if (response.StatusCode != HttpStatusCode.Created)
{
throw new Exception($"Error calling external api: {response.ErrorMessage}");
}
return response;
}
public async Task<RestResponse> Update(T model, string subURL)
{
try
{
var request = new RestRequest(subURL, Method.Put)
{ RequestFormat = DataFormat.Json };
request.AddJsonBody(model);
var response = await _client.ExecuteAsync(request);
if (response.StatusCode == HttpStatusCode.NotFound)
{
throw new Exception($"Post not found: {response.ErrorMessage}");
}
return response;
}
catch (Exception ex)
{
throw new Exception($"Error calling external api: {ex.Message}");
}
}
public async Task<RestResponse> Delete(Int64 Id, string subURL)
{
var request = new RestRequest($"{subURL}/{Id}", Method.Delete);
var response = await _client.ExecuteAsync(request);
Console.WriteLine($"response.StatusCode: {response.StatusCode}");
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception($"Error calling external api: {response.ErrorMessage}");
}
return response;
}
}
}
Add the following to the Program.cs file in the RestSharpDemo.Api project
using RestSharpDemo.Api.Services;
var builder = WebApplication.CreateBuilder(args);
// We used typeof because we are using generics in the ExternalApiService
builder.Services.AddSingleton(typeof(IExternalApiService<>), typeof(ExternalApiService<>));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Add the following to the appsettings.json file in the RestSharpDemo.Api project
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ExternalApi": {
"BaseUrl": "https://jsonplaceholder.typicode.com"
},
"AllowedHosts": "*"
}
Create a new controller in the Controllers folder in the RestSharpDemo.Api project
touch PostsController.cs
using Microsoft.AspNetCore.Mvc;
namespace RestSharpDemo.Api.Controllers
{
[ApiController]
[Route("[controller]")]
public class PostsController : ControllerBase
{
private readonly IExternalApiService<Post> _externalApiService;
public PostsController(IExternalApiService<Post> externalApiService)
{
_externalApiService = externalApiService;
}
[HttpGet]
public async Task<IActionResult> GetAll([FromQuery] Dictionary<string, string> queryParams = null!)
{
string _subURL = "posts";
var result = await _externalApiService.GetAll(_subURL, queryParams);
var output = result
.Take(10)
.OrderByDescending(x => x.Id).
ToList();
return Ok(output);
}
[HttpGet("{id}")]
public async Task<IActionResult> GetById(Int64 id)
{
string _subURL = "posts/";
var result = await _externalApiService.GetById(id, _subURL);
return Ok(result);
}
[HttpPost]
public async Task<IActionResult> Add(PostDto post)
{
string _subURL = "posts/";
var result = await _externalApiService.Add(post, _subURL);
return Ok(result.Content);
}
[HttpPut]
public async Task<IActionResult> Update(PostDto post)
{
string _subURL = "posts/";
var result = await _externalApiService.Update(post, _subURL);
return Ok(result.Content);
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(Int64 id)
{
string _subURL = "posts/";
var result = await _externalApiService.Delete(id, _subURL);
return Ok(result.Content);
}
}
}
Create a new model in the Models folder in the RestSharpDemo.Api project
touch Post.cs
namespace RestSharpDemo.Api
{
public class Post
{
public Int64 Id { get; set; }
public Int64 UserId { get; set; }
public string Title { get; set; }
public string Body { get; set; }
}
}
Run the project
dotnet run --project RestSharpDemo.Api/RestSharpDemo.Api.csproj
Open a browser and navigate to the following url
Conclusion
This is a very simple example of how to make external api calls using RestSharp. You can use this as a starting point to build your own service to make external api calls. Thank you for reading and happy coding! π
Top comments (0)