Search Results for

    Web Layer (ServiceDeskLite.Web)

    API Client

    // ServiceDeskLite.Web.Api.V1
    public interface ITicketsApiClient
    {
        Task<ApiResult<PagedResponse<TicketListItemResponse>>> SearchAsync(
            SearchTicketsRequest request, CancellationToken ct = default);
    
        Task<ApiResult<TicketResponse>> GetByIdAsync(
            Guid id, CancellationToken ct = default);
    
        Task<ApiResult<CreateTicketResponse>> CreateAsync(
            CreateTicketRequest request, CancellationToken ct = default);
    
        Task<ApiResult<TicketResponse>> ChangeStatusAsync(
            Guid id, ChangeTicketStatusRequest request, CancellationToken ct = default);
    
        Task<ApiResult<TicketResponse>> AssignAsync(
            Guid id, AssignTicketRequest request, CancellationToken ct = default);
    
        Task<ApiResult<CommentResponse>> AddCommentAsync(
            Guid id, AddCommentRequest request, CancellationToken ct = default);
    
        Task<ApiResult<IReadOnlyList<AuditEventResponse>>> GetAuditEventsAsync(
            Guid id, CancellationToken ct = default);
    
        Task<ApiResult<DashboardSummaryResponse>> GetDashboardSummaryAsync(
            CancellationToken ct = default);
    }
    

    TicketsApiClient uses HttpClient with PropertyNameCaseInsensitive JSON deserialization and parses ProblemDetails from API error responses. Outgoing requests that carry enum values (e.g. ChangeStatusAsync) are serialised with camelCase + JsonStringEnumConverter.

    ApiKeyDelegatingHandler

    // Attaches the configured API key to every outbound HTTP request.
    // The key is read from Auth:ApiKey at request time so that configuration changes
    // (e.g. via environment variables) take effect without restarting.
    internal sealed class ApiKeyDelegatingHandler(IConfiguration configuration) : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var apiKey = configuration["Auth:ApiKey"];
            if (!string.IsNullOrWhiteSpace(apiKey))
                request.Headers.TryAddWithoutValidation("X-Api-Key", apiKey);
            return base.SendAsync(request, cancellationToken);
        }
    }
    

    This handler is registered as a DelegatingHandler on the typed HttpClient for TicketsApiClient. See ADR 0022.

    ApiResult<T> and ApiError

    public sealed class ApiResult<T>
    {
        public bool IsSuccess => Error is null;
        public T? Value { get; }
        public ApiError? Error { get; }
    
        public static ApiResult<T> Success(T value)
        public static ApiResult<T> Failure(ApiError? error)
    }
    
    public sealed class ApiError
    {
        public int Status { get; init; }
        public string? Title { get; init; }
        public string? Detail { get; init; }
        public string? Code { get; init; }
        public string? ErrorType { get; init; }
        public string? TraceId { get; init; }
        public Dictionary<string, object>? Meta { get; init; }
    }
    

    ProblemDetailsDto

    Internal DTO used to deserialise RFC 9457 error responses from the API before mapping them to ApiError.

    public class ProblemDetailsDto
    {
        public string? Type { get; init; }
        public string? Title { get; init; }
        public int? Status { get; init; }
        public string? Detail { get; init; }
        public string? Instance { get; init; }
    
        [JsonExtensionData]
        public Dictionary<string, JsonElement>? Extensions { get; init; }
    }
    

    [JsonExtensionData] captures all extra fields (code, errorType, traceId, meta) without requiring an explicit property per extension key.

    Client / API Result Types

    Client / API Result Types

    API Client Call Flow

    API Client Call Flow

    Configuration

    // appsettings.Development.json (Web)
    {
        "ApiClient": {
            "BaseUrl": "https://localhost:7238",
            "TimeoutSeconds": 10
        },
        "Auth": {
            "ApiKey": "dev-api-key"
        }
    }
    
    • Edit this page
    In this article
    Back to top Generated by DocFX