Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
<scope>runtime</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
package com.springboot.blog;

import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import org.modelmapper.ModelMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@OpenAPIDefinition(
info = @Info(
title = "Spring Boot Blog App REST APIs",
description = "Spring Boot Blog App REST APIs documentation",
version = "v1.0",
contact = @Contact(
name = "Adilet Kozubaev",
email = "adiletkdev@gmail.com",
url = "https://www.******.net"
),
license = @License(
name = "Apache 2.0",
url = "https://www.******.net/license"
)
),
externalDocs = @ExternalDocumentation(
description = "Spring Boot Blog App documentation",
url = "https://github.com/adiletkdev/springboot-blog-rest-api"
)
)
public class SpringbootBlogRestApiApplication {

@Bean
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/springboot/blog/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.springboot.blog.security.JwtAuthenticationEntryPoint;
import com.springboot.blog.security.JwtAuthenticationFilter;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
Expand All @@ -22,6 +24,12 @@

@Configuration
@EnableMethodSecurity
@SecurityScheme(
name = "Bearer Authentication",
type = SecuritySchemeType.HTTP,
bearerFormat = "JWT",
scheme = "bearer"
)
public class SecurityConfig {

private UserDetailsService userDetailsService;
Expand Down Expand Up @@ -56,6 +64,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//authorize.anyRequest().authenticated()
authorize.requestMatchers(HttpMethod.GET, "/api/**").permitAll()
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/swagger-ui/**").permitAll()
.requestMatchers("/v3/api-docs/**").permitAll()
.anyRequest().authenticated()

).exceptionHandling(exception -> exception
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/com/springboot/blog/controller/PostController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import com.springboot.blog.payload.PostResponse;
import com.springboot.blog.service.PostService;
import com.springboot.blog.utils.AppConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -14,6 +18,9 @@

@RestController
@RequestMapping("/api/posts")
@Tag(
name = "CRUD REST APIs for Post Resource"
)
public class PostController {

private PostService postService;
Expand All @@ -23,13 +30,32 @@ public PostController(PostService postService) {
}

// create blog post
@Operation(
summary = "Create Post REST API",
description = "Create Post REST API is used to save post into database"
)
@ApiResponse(
responseCode = "201",
description = "Http Status 201 CREATED"
)
@SecurityRequirement(
name = "Bearer Authentication"
)
@PreAuthorize("hasRole('ADMIN')")
@PostMapping
public ResponseEntity<PostDto> createPost(@Valid @RequestBody PostDto postDto) {
return new ResponseEntity<>(postService.createPost(postDto), HttpStatus.CREATED);
}

// get all posts rest api
@Operation(
summary = "Get All Posts REST API",
description = "Get All Posts REST API is used to fetch all the posts from the database"
)
@ApiResponse(
responseCode = "200",
description = "Http Status 200 SUCCESS"
)
@GetMapping
public PostResponse getAllPosts(
@RequestParam(value = "pageNo", defaultValue = AppConstants.DEFAULT_PAGE_NUMBER, required = false) int pageNo,
Expand All @@ -41,12 +67,31 @@ public PostResponse getAllPosts(
}

// get post by id
@Operation(
summary = "Get Post by Id REST API",
description = "Get Post by Id REST API is used to get single post from the database"
)
@ApiResponse(
responseCode = "200",
description = "Http Status 200 SUCCESS"
)
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostId(@PathVariable(name = "id") long id) {
return ResponseEntity.ok(postService.getPostById(id));
}

// update post by id rest api
@Operation(
summary = "Update Post REST API",
description = "Update Post REST API is used to update a particular post in the database"
)
@ApiResponse(
responseCode = "200",
description = "Http Status 200 SUCCESS"
)
@SecurityRequirement(
name = "Bearer Authentication"
)
@PreAuthorize("hasRole('ADMIN')")
@PutMapping("/{id}")
public ResponseEntity<PostDto> updatePost(
Expand All @@ -59,6 +104,17 @@ public ResponseEntity<PostDto> updatePost(
}

// delete post rest api
@Operation(
summary = "Delete Post REST API",
description = "Delete Post REST API is used to delete a particular post from the database"
)
@ApiResponse(
responseCode = "200",
description = "Http Status 200 SUCCESS"
)
@SecurityRequirement(
name = "Bearer Authentication"
)
@PreAuthorize("hasRole('ADMIN')")
@DeleteMapping("/{id}")
public ResponseEntity<String> deletePost(@PathVariable(name = "id") long id) {
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/springboot/blog/payload/PostDto.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
package com.springboot.blog.payload;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Data;

import java.util.Set;

@Schema(
description = "PostDto Model Information"
)
@Data
public class PostDto {
private long id;

@Schema(
description = "Blog Post Title"
)
// title should not be null or empty
// title should have at least 2 characters
@NotEmpty
@Size(min = 2, message = "Post title should have at least 2 characters")
private String title;

@Schema(
description = "Blog Post Description"
)
// post description should be null or empty
// post description should have at least 10 characters
@NotEmpty
@Size(min = 10, message = "Post description should have at least 10 characters")
private String description;

@Schema(
description = "Blog Post Content"
)
// post content should not be null or empty
@NotEmpty
private String content;
private Set<CommentDto> comments;

@Schema(
description = "Blog Post Category"
)
private Long categoryId;
}