using Asp.Versioning; using Microsoft.AspNetCore.Mvc; using OliverBooth.Api.Data; using OliverBooth.Common.Data.Blog; using OliverBooth.Common.Services; namespace OliverBooth.Api.Controllers.Blog; /// /// Represents an API controller which allows reading and writing of blog posts. /// [ApiController] [Route("v{version:apiVersion}/blog/post")] [Produces("application/json")] [ApiVersion(1)] public sealed class PostController : ControllerBase { private const int ItemsPerPage = 10; private readonly IBlogPostService _blogPostService; /// /// Initializes a new instance of the class. /// /// The . public PostController(IBlogPostService blogPostService) { _blogPostService = blogPostService; } /// /// Returns a collection of all blog posts on the specified page. /// /// The page number. /// An array of objects. [HttpGet("all/{page:int?}")] [EndpointDescription("Returns a collection of all blog posts on the specified page.")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BlogPost[]))] public IActionResult All(int page = 0) { IReadOnlyList allPosts = _blogPostService.GetBlogPosts(page, ItemsPerPage); return Ok(allPosts.Select(post => BlogPost.FromBlogPost(post, _blogPostService))); } /// /// Returns the number of publicly published blog posts. /// /// The number of publicly published blog posts. [HttpGet("count")] [EndpointDescription("Returns the number of publicly published blog posts.")] [ProducesResponseType(StatusCodes.Status200OK)] public IActionResult Count() { return Ok(new { count = _blogPostService.GetBlogPostCount() }); } /// /// Returns an object representing the blog post with the specified ID. /// /// The ID of the blog post. /// An object representing the blog post. [HttpGet("{id:guid}")] [EndpointDescription("Returns an object representing the blog post with the specified ID.")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BlogPost))] [ProducesResponseType(StatusCodes.Status404NotFound)] public IActionResult GetPost(Guid id) { if (!_blogPostService.TryGetPost(id, out IBlogPost? post)) { return NotFound(); } return Ok(BlogPost.FromBlogPost(post, _blogPostService, true)); } /// /// Returns a collection of all blog posts which contain the specified tag on the specified page. /// /// The tag for which to search. /// The page number. /// An array of objects. [HttpGet("tagged/{tag}/{page:int?}")] [EndpointDescription("Returns a collection of all blog posts which contain the specified tag on the specified page.")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BlogPost[]))] public IActionResult Tagged(string tag, int page = 0) { tag = tag.Replace('-', ' ').ToLowerInvariant(); IReadOnlyList allPosts = _blogPostService.GetBlogPosts(page, ItemsPerPage); allPosts = allPosts.Where(post => post.Tags.Contains(tag)).ToList(); return Ok(allPosts.Select(post => BlogPost.FromBlogPost(post, _blogPostService))); } }