using Api.Services; using Microsoft.AspNetCore.Mvc; using PageFetcher.Models; using Swashbuckle.AspNetCore.Annotations; namespace Api.Controllers; /// /// Handles page-fetch requests: navigates to the URL via Playwright and returns rendered HTML and extracted text. /// [ApiController] [Route("api/page")] public sealed class PageController : ControllerBase { private readonly PageFetcherService _service; private readonly ILogger _logger; public PageController(PageFetcherService service, ILogger logger) { _service = service; _logger = logger; } /// /// Fetches a web page via headless Chromium. /// Returns rendered HTML and extracted plain text. /// [HttpPost("fetch")] [SwaggerOperation(Summary = "Fetch a web page", Description = "Navigates to the given URL using Playwright, returns rendered HTML and stripped plain text.")] [SwaggerResponse(StatusCodes.Status200OK, "Page fetched successfully", typeof(FetchPageResponse))] [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid or non-HTTP(S) URL")] public async Task> Fetch([FromBody] FetchPageRequest request, CancellationToken ct) { if (string.IsNullOrWhiteSpace(request.Url)) return BadRequest(new { Error = "Url is required." }); if (!Uri.TryCreate(request.Url, UriKind.Absolute, out var uri) || (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)) return BadRequest(new { Error = "Url must be an absolute HTTP or HTTPS URL." }); _logger.LogInformation("Fetch request: {Url} | caller={Caller} | waitFor={WaitFor}", request.Url, request.CallerService, request.WaitFor); var result = await _service.FetchAsync(request, ct); return Ok(result); } }