Blog APIs implemented

This commit is contained in:
Bangara Raju Kottedi 2024-05-07 02:31:50 +05:30
parent 50c5f87f93
commit d8c59d7bd1
6 changed files with 110 additions and 12 deletions

View File

@ -1,6 +1,7 @@
using Asp.Versioning;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using PortBlog.API.Entities;
using PortBlog.API.Models;
using PortBlog.API.Repositories.Contracts;
@ -18,29 +19,35 @@ namespace PortBlog.API.Controllers
public BlogController(ILogger<BlogController> logger, IBlogRepository blogRepository, IMapper mapper)
{
this._logger = logger;
this._blogRepository = blogRepository;
this._mapper = mapper;
_logger = logger;
_blogRepository = blogRepository;
_mapper = mapper;
}
[HttpGet("GetPostLikesAndViews")]
public async Task<ActionResult> GetPostLikesAndViews(string blogUrl, string postSlug)
public async Task<ActionResult<PostMetricsDto>> GetPostLikesAndViews(string blogUrl, string postSlug)
{
var postMetrics = new PostMetricsDto();
if(!await this._blogRepository.BlogExistsAsync(blogUrl))
if(!await _blogRepository.BlogExistsAsync(blogUrl))
{
_logger.LogInformation($"Blog with id {blogUrl} wasn't found when fetching post likes and views.");
return NotFound();
}
if (!await this._blogRepository.PostExistsAsync(blogUrl, postSlug))
if (!await _blogRepository.PostExistsAsync(blogUrl, postSlug))
{
_logger.LogInformation($"Post with id {postSlug} wasn't found when fetching post likes and views.");
return Ok(postMetrics);
}
var post = await _blogRepository.GetPostLikesAndViewsAsync(blogUrl, postSlug);
var post = await _blogRepository.GetPostAsync(blogUrl, postSlug);
post.Views++;
_blogRepository.UpdatePost(post);
await _blogRepository.SaveChangesAsync();
postMetrics = _mapper.Map<PostMetricsDto>(post);
@ -48,5 +55,72 @@ namespace PortBlog.API.Controllers
return Ok(postMetrics);
}
[HttpPost("CreatePost")]
public async Task<ActionResult<PostMetricsDto>> CreatePost([FromBody] PostCreationDto post)
{
if (!await _blogRepository.BlogExistsAsync(post.BlogUrl))
{
_logger.LogInformation($"Blog with id {post.BlogUrl} wasn't found when fetching post likes and views.");
return NotFound();
}
var postEntityExists = await _blogRepository.GetPostAsync(post.BlogUrl, post.Slug);
if (postEntityExists == null)
{
postEntityExists = _mapper.Map<Post>(post);
postEntityExists.Views++;
_blogRepository.AddPost(postEntityExists);
await _blogRepository.SaveChangesAsync();
}
var postMetrics = _mapper.Map<PostMetricsDto>(postEntityExists);
postMetrics.PostExists = true;
return Ok(postMetrics);
}
[HttpPost("LikePost")]
public async Task<ActionResult<int>> LikePost(string blogUrl, string postSlug)
{
if (!await _blogRepository.PostExistsAsync(blogUrl, postSlug))
{
_logger.LogInformation($"Post with id {postSlug} wasn't found when fetching post likes and views.");
return NotFound();
}
var post = await _blogRepository.GetPostAsync(blogUrl, postSlug);
post.Likes++;
_blogRepository.UpdatePost(post);
await _blogRepository.SaveChangesAsync();
return Ok(post.Likes);
}
[HttpPost("DislikePost")]
public async Task<ActionResult<int>> DislikePost(string blogUrl, string postSlug)
{
if (!await _blogRepository.PostExistsAsync(blogUrl, postSlug))
{
_logger.LogInformation($"Post with id {postSlug} wasn't found when fetching post likes and views.");
return NotFound();
}
var post = await _blogRepository.GetPostAsync(blogUrl, postSlug);
post.Likes--;
_blogRepository.UpdatePost(post);
await _blogRepository.SaveChangesAsync();
return Ok(post.Likes);
}
}
}

View File

@ -1,6 +1,6 @@
namespace PortBlog.API.Models
{
public class PostCreatedDto
public class PostCreationDto
{
public int PostId { get; set; }
@ -25,5 +25,7 @@
public string? CreatedDate { get; set; }
public string? ModifiedDate { get; set; }
public string BlogUrl { get; set;} = string.Empty;
}
}

View File

@ -19,6 +19,7 @@ namespace PortBlog.API.Profiles
opts => opts.MapFrom(src => src.ModifiedDate != null ? src.ModifiedDate.Value.ToString("MMM dd, yyyy") : string.Empty)
);
CreateMap<Post, PostMetricsDto>();
CreateMap<PostCreationDto, Post>();
}
}
}

View File

@ -50,7 +50,7 @@ if (!String.IsNullOrEmpty(allowedCorsOrigins.Value))
policy =>
{
policy.WithOrigins(origins);
policy.WithHeaders("XApiKey");
policy.AllowAnyHeader();
});
});
}

View File

@ -24,7 +24,7 @@ namespace PortBlog.API.Repositories
return await _cvBlogContext.Blogs.Where(b => b.BlogUrl == blogUrl).FirstOrDefaultAsync();
}
public async Task<Post?> GetPostLikesAndViewsAsync(string blogUrl, string postSlug)
public async Task<Post?> GetPostAsync(string blogUrl, string postSlug)
{
return await _cvBlogContext.Posts.Where(p => p.Slug == postSlug && p.BlogUrl == blogUrl).FirstOrDefaultAsync();
}
@ -37,7 +37,22 @@ namespace PortBlog.API.Repositories
public async Task<bool> BlogExistsAsync(string blogUrl)
{
return await _cvBlogContext.Posts.AnyAsync(b => b.BlogUrl == blogUrl);
return await _cvBlogContext.Blogs.AnyAsync(b => b.BlogUrl == blogUrl);
}
public void AddPost(Post post)
{
_cvBlogContext.Posts.Add(post);
}
public void UpdatePost(Post post)
{
_cvBlogContext.Posts.Update(post);
}
public async Task<bool> SaveChangesAsync()
{
return (await _cvBlogContext.SaveChangesAsync() >= 0);
}
}
}

View File

@ -6,10 +6,16 @@ namespace PortBlog.API.Repositories.Contracts
{
Task<Blog?> GetBlogAsync(string blogUrl, bool includePosts);
Task<Post> GetPostLikesAndViewsAsync(string blogUrl, string postSlug);
Task<Post> GetPostAsync(string blogUrl, string postSlug);
Task<bool> PostExistsAsync(string blogUrl, string postSlug);
Task<bool> BlogExistsAsync(string blogUrl);
void AddPost(Post post);
void UpdatePost(Post post);
Task<bool> SaveChangesAsync();
}
}