Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2c94978
feat: book domain
becooq81 Aug 15, 2024
4fd0836
log:둜그찍기
jimmy0006 Aug 20, 2024
cd72e13
feat:add transactional
jimmy0006 Aug 20, 2024
324826b
fix:see notification when not logged in
jimmy0006 Aug 28, 2024
edb8c10
fix:sync with mater branch
jimmy0006 Dec 3, 2024
0441cf6
github actions test
jimmy0006 Dec 3, 2024
581e923
feat: add dependency for jackson
becooq81 Dec 3, 2024
1f25cfb
feat: implement book client interface/naver book implementation
becooq81 Dec 3, 2024
f9e1792
feat: add controller endpoint to search books per page
becooq81 Dec 3, 2024
f8e14f9
refactor: replace with all args constructor annotation
becooq81 Dec 3, 2024
4e20b02
feat: add payload to contain individual book api response
becooq81 Dec 3, 2024
b1073de
feat: add payload to contain complete xml response
becooq81 Dec 3, 2024
9518e59
feat: use rest template config to set up bean for singleton pattern
becooq81 Dec 3, 2024
8ed3638
doc: add env variables for naver book api
becooq81 Dec 3, 2024
c7b25a4
refactor: organize book dtos into request and response
becooq81 Dec 3, 2024
b1b94aa
feat: add book module endpoints
becooq81 Dec 3, 2024
db5b336
feat: extend field sizes
becooq81 Dec 3, 2024
f6823f2
feat: add create book request
becooq81 Dec 3, 2024
5b1a221
feat: add update book request
becooq81 Dec 3, 2024
f935895
feat: add book response
becooq81 Dec 3, 2024
d656f43
feat: add book repository methods
becooq81 Dec 3, 2024
1ff0c5f
feat: implement book service interface/impl
becooq81 Dec 3, 2024
a8b74f0
comment: comment out book tests
becooq81 Dec 3, 2024
5ef2af1
feat: add validation to page
becooq81 Dec 3, 2024
d29e3c3
Merge branch 'master' into dev
becooq81 Dec 3, 2024
5aef755
chore: remove printing statement
becooq81 Dec 15, 2024
38d7a91
feat(controller): add sorting option as request parameter for full vi…
becooq81 Dec 15, 2024
d2f50fa
rename: rename borrow to rent
becooq81 Dec 15, 2024
d147351
feat: add donor column
becooq81 Dec 15, 2024
9b58927
feat: add book sort option enum as options for sorting books
becooq81 Dec 15, 2024
a913dda
fix: fix annotations for validating dto fields
becooq81 Dec 15, 2024
762eb20
feat: add donor & borrower to book response
becooq81 Dec 15, 2024
99a9f2a
feat(repo): add find all methods with sorting options
becooq81 Dec 15, 2024
21230aa
chore: add import
becooq81 Dec 15, 2024
bafd9a2
feat(service): add sorting options
becooq81 Dec 15, 2024
e9f8da4
feat(service): add donor to book saving logic
becooq81 Dec 15, 2024
0a8f61a
Merge pull request #11 from PoolC/feat/book
becooq81 Dec 15, 2024
ff2a370
fix:add data type and returns null when error
jimmy0006 Dec 21, 2024
a3a659b
feat:add book tag and search option
jimmy0006 Feb 8, 2025
b5fb654
feat:add sort option when search book
jimmy0006 Feb 11, 2025
6174174
fix:search book method fixed
jimmy0006 Mar 24, 2025
d1d9c57
fix:github actions retry
jimmy0006 Mar 24, 2025
b04c44a
fix:add Cors Origin
jimmy0006 Jul 10, 2025
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
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ compiler(`⌘,` > `Build, Execution, Deployment` > `Compiler` > `Java Compiler`
./gradlew asciidoctor
```


`/build/asciidoc/html5/api-doc.html` μ—μ„œ api λ¬Έμ„œλ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.


Expand Down
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ dependencies {
implementation 'org.hibernate:hibernate-core'
implementation 'org.hibernate:hibernate-entitymanager'

implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.18.1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.18.1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.18.1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.18.1'
//compile group: 'io.springfox', name: 'springfox-swagger2', version: '3.0.0'
//compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/poolc/api/activity/domain/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ public int hashCode() {
return Objects.hash(getId(), getActivity(), getDescription(), getDate(), getSessionNumber());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Arrays.asList(
"https://alpha.poolc.org", "http://localhost:3000",
"https://server.poolc.kr", "http://server.poolc.kr",
"http://poolc.kr","https://poolc.kr",
"https://poolc.org", "http://poolc.org","https://poolc.org/api", "http://poolc.org/api",
"https://dev.poolc.org", "http://dev.poolc.org","https://dev.poolc.org/api", "http://dev.poolc.org/api",
"http://localhost:3000",
"https://poolc.org", "http://poolc.org"
,"https://poolc.org/api", "http://poolc.org/api",
"https://dev.poolc.org", "http://dev.poolc.org"
,"https://api.poolc.org","http://api.poolc.org",
"chrome-extension://doeamknhlolnflkmhbhkagganhjjbefe"
));
configuration.setAllowedHeaders(Arrays.asList(
Expand Down Expand Up @@ -96,6 +96,7 @@ protected void configure(HttpSecurity http) throws Exception {
.antMatchers(HttpMethod.GET, "/book").permitAll()
.antMatchers(HttpMethod.GET, "/book/*").permitAll()
.antMatchers(HttpMethod.POST, "/book").hasAuthority(MemberRole.ADMIN.name())
.antMatchers(HttpMethod.POST, "/book/*").hasAuthority(MemberRole.ADMIN.name())
.antMatchers(HttpMethod.PUT, "/book/*").hasAuthority(MemberRole.ADMIN.name())
.antMatchers(HttpMethod.DELETE, "/book/*").hasAuthority(MemberRole.ADMIN.name())
.antMatchers(HttpMethod.PUT, "/book/borrow/*").hasAuthority(MemberRole.MEMBER.name())
Expand Down
17 changes: 8 additions & 9 deletions src/main/java/org/poolc/api/badge/service/BadgeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,16 @@ public Badge getBadgeByBadgeId(Long badgeId){
}

//뱃지가 μ‘΄μž¬ν•˜κ³ , ν•΄λ‹Ή 뱃지λ₯Ό 받은 적이 없을 κ²½μš°μ—λ§Œ 지급함
@Transactional
public void badgeGiver(Member member, Long badgeId){
if(duplicateBadgeLogCheck(badgeId, member)&&badgeRepository.findBadgeById(badgeId).isPresent()){
if(badgeLogRepository.findBadgeLogByUUID(member.getUUID(),badgeId).isEmpty()) {
Badge badge = getBadgeByBadgeId(badgeId);
badgeLogRepository.save(BadgeLog.builder()
.member(member)
.date(LocalDate.now())
.badge(badge)
.build());
notificationService.createBadgeNotification(member);
}
Badge badge = getBadgeByBadgeId(badgeId);
badgeLogRepository.save(BadgeLog.builder()
.member(member)
.date(LocalDate.now())
.badge(badge)
.build());
notificationService.createBadgeNotification(member);
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/org/poolc/api/book/client/BookClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.poolc.api.book.client;

import org.poolc.api.book.dto.response.BookApiResponse;

import javax.management.modelmbean.XMLParseException;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use appropriate exception type for XML parsing.

The import javax.management.modelmbean.XMLParseException is incorrect for general XML parsing. This exception is specifically for JMX management beans, not for parsing XML responses from external APIs.

Consider using a more appropriate exception type:

-import javax.management.modelmbean.XMLParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;

And update the method signature:

-    List<BookApiResponse> searchBooks(String query, int page) throws XMLParseException;
+    List<BookApiResponse> searchBooks(String query, int page) throws JsonProcessingException;

Alternatively, you could use a more general exception like Exception or create a custom exception class for book client operations.

πŸ€– Prompt for AI Agents
In src/main/java/org/poolc/api/book/client/BookClient.java at line 5, replace
the incorrect import of javax.management.modelmbean.XMLParseException with a
more appropriate XML parsing exception such as org.xml.sax.SAXException or
javax.xml.parsers.ParserConfigurationException depending on the XML parsing
library used. Also, update any method signatures and exception handling code to
reflect this change, or alternatively use a general Exception or define a custom
exception class for book client errors.

import java.util.List;

public interface BookClient {

List<BookApiResponse> searchBooks(String query, int page) throws XMLParseException;

}
64 changes: 64 additions & 0 deletions src/main/java/org/poolc/api/book/client/NaverBookClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.poolc.api.book.client;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.RequiredArgsConstructor;
import org.poolc.api.book.dto.response.BookApiResponse;
import org.poolc.api.book.dto.response.NaverApiResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.management.modelmbean.XMLParseException;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

⚠️ Potential issue

Use appropriate exception type for XML parsing

XMLParseException from javax.management.modelmbean is not intended for general XML parsing errors. Consider using a more appropriate exception type.

Options:

  1. Create a custom exception: BookApiException or XmlParsingException
  2. Use org.springframework.web.client.RestClientException
  3. Use com.fasterxml.jackson.core.JsonProcessingException (which XmlMapper actually throws)
πŸ€– Prompt for AI Agents
In src/main/java/org/poolc/api/book/client/NaverBookClient.java at line 14,
replace the import of javax.management.modelmbean.XMLParseException with a more
appropriate exception type for XML parsing errors. You can either create a
custom exception like BookApiException or XmlParsingException, or use an
existing relevant exception such as
org.springframework.web.client.RestClientException or
com.fasterxml.jackson.core.JsonProcessingException, which is actually thrown by
XmlMapper. Update the import and exception handling accordingly to reflect this
change.

import java.util.List;

@Component
@RequiredArgsConstructor
public class NaverBookClient implements BookClient{

@Value("${book.api.url}")
private String url;

@Value("${book.api.secret}")
private String clientSecret;

@Value("${book.api.id}")
private String clientId;

private final RestTemplate restTemplate;

private static final int PAGE_SIZE = 10;

@Override
public List<BookApiResponse> searchBooks(String query, int page) throws XMLParseException {
HttpHeaders headers = new HttpHeaders();
headers.set("X-Naver-Client-Id", clientId);
headers.set("X-Naver-Client-Secret", clientSecret);

HttpEntity<String> entity = new HttpEntity<>(headers);

String url = new StringBuilder(this.url)
.append("?query=").append(query)
.append("&display=").append(PAGE_SIZE)
.append("&start=").append(page * PAGE_SIZE + 1)
.toString();
Comment on lines +42 to +46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

URL encode query parameter to handle special characters

The query parameter should be URL encoded to properly handle special characters, spaces, and non-ASCII text.

Add URL encoding:

+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;

         String url = new StringBuilder(this.url)
-                .append("?query=").append(query)
+                .append("?query=").append(URLEncoder.encode(query, StandardCharsets.UTF_8))
                 .append("&display=").append(PAGE_SIZE)
                 .append("&start=").append(page * PAGE_SIZE + 1)
                 .toString();
πŸ€– Prompt for AI Agents
In src/main/java/org/poolc/api/book/client/NaverBookClient.java around lines 42
to 46, the query parameter in the URL is not URL encoded, which can cause issues
with special characters and spaces. Fix this by applying URL encoding to the
query string before appending it to the URL. Use a standard encoding method like
URLEncoder.encode(query, "UTF-8") to ensure proper encoding of the query
parameter.


String xmlResponse = restTemplate.exchange(url, HttpMethod.GET, entity, String.class).getBody();


try {
NaverApiResponse naverApiResponse = parseBooks(xmlResponse);
return naverApiResponse.getChannel().getItems();
} catch (Exception e) {
e.printStackTrace();
throw new XMLParseException("Failed to parse XML response");
}
}
Comment on lines +51 to +58
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

⚠️ Potential issue

Improve error handling and logging

Several issues with the current error handling:

  1. Using printStackTrace() instead of proper logging
  2. Catching generic Exception is too broad
  3. Error message doesn't include original error details
+import lombok.extern.slf4j.Slf4j;

+@Slf4j
 @Component
 @RequiredArgsConstructor
 public class NaverBookClient implements BookClient{

         try {
             NaverApiResponse naverApiResponse = parseBooks(xmlResponse);
             return naverApiResponse.getChannel().getItems();
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new XMLParseException("Failed to parse XML response");
+        } catch (JsonProcessingException e) {
+            log.error("Failed to parse XML response from Naver API", e);
+            throw new RuntimeException("Failed to parse XML response from Naver API", e);
         }

Committable suggestion skipped: line range outside the PR's diff.

πŸ€– Prompt for AI Agents
In src/main/java/org/poolc/api/book/client/NaverBookClient.java around lines 51
to 58, replace the generic Exception catch with a more specific exception
related to XML parsing, use a proper logging framework instead of
printStackTrace(), and include the original exception's message or stack trace
in the XMLParseException to preserve error details for debugging.


private NaverApiResponse parseBooks(String xmlResponse) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
return xmlMapper.readValue(xmlResponse, NaverApiResponse.class);
}
Comment on lines +60 to +63
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Reuse XmlMapper instance for better performance

Creating a new XmlMapper instance for each request is inefficient. Consider creating it once and reusing it.

+    private static final XmlMapper xmlMapper = new XmlMapper();

     private NaverApiResponse parseBooks(String xmlResponse) throws Exception {
-        XmlMapper xmlMapper = new XmlMapper();
         return xmlMapper.readValue(xmlResponse, NaverApiResponse.class);
     }
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private NaverApiResponse parseBooks(String xmlResponse) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
return xmlMapper.readValue(xmlResponse, NaverApiResponse.class);
}
private static final XmlMapper xmlMapper = new XmlMapper();
private NaverApiResponse parseBooks(String xmlResponse) throws Exception {
return xmlMapper.readValue(xmlResponse, NaverApiResponse.class);
}
πŸ€– Prompt for AI Agents
In src/main/java/org/poolc/api/book/client/NaverBookClient.java around lines 60
to 63, the method parseBooks creates a new XmlMapper instance every time it is
called, which is inefficient. To fix this, declare a private static final
XmlMapper instance as a class field and reuse this single instance inside the
parseBooks method instead of creating a new one each time.

}
137 changes: 97 additions & 40 deletions src/main/java/org/poolc/api/book/controller/BookController.java
Original file line number Diff line number Diff line change
@@ -1,70 +1,127 @@
package org.poolc.api.book.controller;

import lombok.RequiredArgsConstructor;
import org.poolc.api.book.dto.BookRequest;
import org.poolc.api.book.dto.BookResponse;
import org.poolc.api.book.client.BookClient;
import org.poolc.api.book.domain.BookSearchOption;
import org.poolc.api.book.domain.BookSortOption;
import org.poolc.api.book.dto.request.CreateBookRequest;
import org.poolc.api.book.dto.request.UpdateBookRequest;
import org.poolc.api.book.dto.response.BookApiResponse;
import org.poolc.api.book.dto.response.BookResponse;
import org.poolc.api.book.service.BookService;
import org.poolc.api.book.vo.BookCreateValues;
import org.poolc.api.book.vo.BookUpdateValues;
import org.poolc.api.member.domain.Member;
import org.springframework.http.MediaType;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import java.util.List;

import static java.util.stream.Collectors.toList;

@RestController
@RequiredArgsConstructor
@RequestMapping("/book")
@RequiredArgsConstructor
public class BookController {

private final BookClient bookClient;
private final BookService bookService;

@GetMapping(value = "/{bookID}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<BookResponse> findOneBookWithBorrower(@PathVariable("bookID") Long id) {
return ResponseEntity.ok().body(BookResponse.of(bookService.findOneBook(id)));
@GetMapping("/naver/search")
public ResponseEntity<List<BookApiResponse>> searchBooksFromAPI(@RequestParam String query,
@RequestParam(value = "page", defaultValue = "0") @Min(0) Integer page) {
try {
return new ResponseEntity<>(bookClient.searchBooks(query, page), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Comment on lines +31 to +39
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Improve error handling with specific HTTP status codes.

The generic catch-all exception handling returns 500 for all errors, making it difficult to distinguish between validation errors (400), not found (404), unauthorized (403), etc. Consider using @ExceptionHandler or returning appropriate status codes based on exception types.

Example approach:

@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleBadRequest(IllegalArgumentException e) {
    return ResponseEntity.badRequest().body(e.getMessage());
}

@ExceptionHandler(BookNotFoundException.class) 
public ResponseEntity<String> handleNotFound(BookNotFoundException e) {
    return ResponseEntity.notFound().build();
}

Also applies to: 41-52, 54-63, 65-72, 74-83, 85-93, 95-104, 106-114, 116-124

πŸ€– Prompt for AI Agents
In src/main/java/org/poolc/api/book/controller/BookController.java around lines
31 to 39, the current error handling catches all exceptions and returns a
generic 500 status, which obscures specific error causes. Refactor by removing
the generic try-catch in the controller method and instead implement specific
@ExceptionHandler methods in the controller for different exception types like
IllegalArgumentException (return 400 Bad Request), BookNotFoundException (return
404 Not Found), and others as needed. This will allow returning precise HTTP
status codes based on the exception type and improve API error clarity. Apply
the same pattern to other similar methods in the specified line ranges.


@GetMapping("/search")
public ResponseEntity<Page<BookResponse>> searchBooks(
@RequestParam(value = "page", defaultValue = "0") @Min(0) Integer page,
@RequestParam(value = "search", required = true)BookSearchOption searchOption,
@RequestParam(value = "keyword", required = true) String keyword,
@RequestParam(value = "sort", required = false) BookSortOption sortOption) {
try {
return new ResponseEntity<>(bookService.searchBooks(page,searchOption,keyword,sortOption), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<HashMap<String, List<BookResponse>>> findBooks() {
HashMap<String, List<BookResponse>> responseBody = new HashMap<>();
responseBody.put("data", bookService.findBooks().stream()
.map(BookResponse::of)
.collect(toList()));
return ResponseEntity.ok().body(responseBody);
@GetMapping("/all")
public ResponseEntity<Page<BookResponse>> getAllBooks(
@RequestParam(value = "page", defaultValue = "0") @Min(0) Integer page,
@RequestParam(value = "sort", required = false) BookSortOption sortOption) {
try {
return new ResponseEntity<>(bookService.getAllBooks(page, sortOption), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> registerBook(@RequestBody BookRequest requestBody) {
bookService.saveBook(new BookCreateValues(requestBody));
return ResponseEntity.ok().build();
@GetMapping("/{id}")
public ResponseEntity<BookResponse> getBook(@PathVariable Long id) {
try {
return new ResponseEntity<>(bookService.getBook(id), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@DeleteMapping(value = "/{bookID}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> deleteBook(@PathVariable("bookID") Long id) {
bookService.deleteBook(id);
return ResponseEntity.ok().build();
@PostMapping("/new")
public ResponseEntity<Void> addBook(@AuthenticationPrincipal Member member,
@Valid @RequestBody CreateBookRequest request) {
try {
bookService.createBook(member, request);
return new ResponseEntity<>(HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@PutMapping(value = "/{bookID}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> updateBook(@RequestBody BookRequest requestBody, @PathVariable("bookID") Long id) {
bookService.updateBook(id, new BookUpdateValues(requestBody));
return ResponseEntity.ok().build();
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBook(@AuthenticationPrincipal Member member, @PathVariable Long id) {
try {
bookService.deleteBook(member, id);
return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@PutMapping(value = "/borrow/{bookID}")
public ResponseEntity borrowBook(@AuthenticationPrincipal Member member, @PathVariable("bookID") Long id) {
bookService.borrowBook(member, id);
return ResponseEntity.ok().build();
@PutMapping("/{id}")
public ResponseEntity<Void> updateBook(@AuthenticationPrincipal Member member, @PathVariable Long id,
@Valid @RequestBody UpdateBookRequest request) {
try {
bookService.updateBook(member, id, request);
return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@PutMapping(value = "/return/{bookID}")
public ResponseEntity returnBook(@AuthenticationPrincipal Member member, @PathVariable("bookID") Long id) {
bookService.returnBook(member, id);
return ResponseEntity.ok().build();
@PostMapping("/{id}/borrow")
public ResponseEntity<Void> borrowBook(@AuthenticationPrincipal Member member, @PathVariable Long id) {
try {
bookService.rent(member, id);
return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

@PostMapping("/{id}/return")
public ResponseEntity<Void> returnBook(@AuthenticationPrincipal Member member, @PathVariable Long id) {
try {
bookService.returnBook(member, id);
return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}


}
Loading