Am I using RestSharp correctly in the Function App? It works pretty well, but I'm trying to understand if/how I should reuse the RestClient. I'm also using Azure Service Bus, and I'm setting a static ServiceBusClient and ServiceBusSender.
Reusing RestClient looks tricky because I need to get an authentication token. I suppose I could use a static RestClient for making the token request (which includes a varying host name for the primary request). But how should I make the RestClient static when it needs to use a varying token and host?
This is what I have right now. I'm still on the learning curve with Azure and Function Apps, so any advice on improving this app would be appreciated.
public class Function1
{
private readonly ILogger<Function1> _logger;
// Static reusables
private static ServiceBusClient client = new ServiceBusClient(System.Environment.GetEnvironmentVariable("AzureWebJobsServiceBus"));
private static ServiceBusSender sender = client.CreateSender("emailutilititylogger");
public Function1(ILogger<Function1> log)
{
_logger = log;
}
[FunctionName("EmailReceipt")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiRequestBody("application/json", typeof(ResponsysRequest), Description = "JSON request body")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Auth), Description = "The OK response")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
//Log
var logMessage = new LogMessage();
logMessage.payload = requestBody;
logMessage.timestamp = System.DateTime.Now;
string logMessageString = JsonConvert.SerializeObject(logMessage);
ServiceBusMessage busmsg = new ServiceBusMessage(logMessageString);
await sender.SendMessageAsync(busmsg);
Task<Auth> getAccessToken = GenerateAccessObject();
Auth auth = await getAccessToken;
EmailRequest emailRequest = JsonConvert.DeserializeObject<EmailRequest>(requestBody);
ResponsysRequest responsysRequest = emailRequest.ToResponsys();
var resp = await sendEmail(responsysRequest, auth, emailRequest.EmailData.Campaign);
if (resp.IsSuccessful)
{
var responsysSuccess = JsonConvert.DeserializeObject<List<Response>>(resp.Content);
return new OkObjectResult(responsysSuccess);
}
else
{
var responsysError = JsonConvert.DeserializeObject<ResponsysErrorResponse>(resp.Content);
return new BadRequestObjectResult(responsysError);
}
}
private async Task<Auth> GenerateAccessObject()
{
using var client = new RestClient("https://this.com/rest/api/");
var request = new RestRequest("auth/token");
var response = await client.PostAsync<Auth>(request);
return response;
}
private async Task<RestResponse> sendEmail(ResponsysRequest requestBody, Auth auth, string campaign)
{
using var client = new RestClient(auth.endPoint);
var request = new RestRequest("/rest/campaigns/" + campaign + "/email", Method.Post);
request.AddHeader("Authorization", auth.authToken);
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(requestBody);
var restResponse = await client.ExecutePostAsync(request);
return restResponse;
}