Skip to content

feat: implement search endpoints for posts and users (#19) - #54

Open
TheVicky1 wants to merge 1 commit into
ohbus:masterfrom
TheVicky1:feat/search-endpoints-issue-19
Open

TheVicky1 wants to merge 1 commit into
ohbus:masterfrom
TheVicky1:feat/search-endpoints-issue-19

Conversation

@TheVicky1

Copy link
Copy Markdown

Summary

This pull request implements the search endpoints requested in #19. It introduces dedicated REST endpoints for searching posts, searching users, and performing combined searches, backed by case-insensitive JPA queries and strict validation rules.

Closes #19


Architectural Design & Layering

The implementation follows the established Controller -> Service -> Repository architecture:

  1. Controller Layer (SearchController.java):

    • GET /v1/search: Combined search returning a composite payload of users and posts.
    • GET /v1/search/posts: Paginated search across post content (text).
    • GET /v1/search/users: Paginated search across user attributes (username, name, bio).
    • Annotated with @Timed(value = "moo.search.timer") for latency monitoring.
    • Annotated with @Counted metrics (moo.search.all, moo.search.posts, moo.search.users).
    • Enforces sort parameter validation via Utility.validatePageable(...).
  2. Service Layer (SearchService.java, SearchServiceImpl.java):

    • Marked with @Transactional(readOnly = true).
    • Strips leading @ characters for user handle queries so that searches for @alice and alice both succeed.
    • Trims surrounding whitespace and validates query boundaries.
    • Rejects null, empty, or blank queries with a descriptive HTTP 400 BadRequestException.
    • Enforces a maximum query length of 100 characters to prevent excessive processing overhead.
    • Escapes SQL LIKE wildcard characters (\, %, _) to guard against wildcard pattern injection.
    • Maps entity models to public DTO records (PostModel, UserModel, SearchResultModel) using existing MapStruct mappers (PostMapper, UserMapper).
  3. Repository Layer (PostsRepository.java, UsersRepository.java):

    • Added searchPosts(@Param("query") @NonNull String query, @NonNull Pageable pageable) with case-insensitive lower(...) comparison and ESCAPE '\\'.
    • Added searchUsers(@Param("query") @NonNull String query, @NonNull Pageable pageable) matching against username, name, and bio with case-insensitive lower(...) comparison and ESCAPE '\\'.
  4. Exception Handling (ControllerExceptionHandler.java):

    • Added MissingServletRequestParameterException.class to malformedRequestExceptionHandler to ensure missing q parameters return a clean HTTP 400 Bad Request response.
  5. Build Support (pom.xml):

    • Added quotes around -javaagent in the Maven Surefire configuration to prevent JVM argument splitting on directory paths containing spaces.

Edge Cases and Defenses

  • SQL Wildcard Safety: Escapes \, %, and _ characters to prevent wildcard denial-of-service and unintended full table scans.
  • Query Validation: Missing q returns HTTP 400. Blank or whitespace-only queries return HTTP 400. Queries exceeding 100 characters return HTTP 400.
  • Sort Parameter Injection: Unapproved sort properties (for example, attempting to sort by password) are caught by Utility.validatePageable and return HTTP 400.
  • Case Sensitivity: Explicit lower(...) wrapping in JPQL guarantees consistent case-insensitive searches across MySQL and H2 database collations.
  • Authentication: Unauthenticated requests return HTTP 401 Unauthorized, while Swagger UI and /v3/api-docs remain accessible.

Verification and Test Coverage

  • Unit Tests:
    • SearchServiceImplTest: Tests blank queries, queries over 100 characters, whitespace trimming, wildcard escaping, leading @ strip, and empty page responses.
    • SearchControllerTest: Tests controller delegation, pagination parameters, and rejection of invalid sort properties.
  • Security Tests:
    • SecurityMvcTest: Verified search endpoints require authentication.
  • Integration Tests:
    • TwitterBackendApplicationTests: Verified case-insensitive search queries against the database for users, user handles, and post content.
  • Full Test Suite: All 92 tests passing (0 failures, 0 errors, 0 skipped).
  • Code Style: Checked with Spotless (./mvnw spotless:check), keeping all 77 repository files compliant with Google Java Format.

- Add SearchController with endpoints for /v1/search, /v1/search/posts, and /v1/search/users
- Add SearchService and SearchServiceImpl with query validation, wildcard escaping, and @-handle handling
- Add JPQL search queries to PostsRepository and UsersRepository
- Add SearchResultModel DTO record and wire MapStruct mappers
- Add ControllerExceptionHandler mapping for MissingServletRequestParameterException
- Add unit tests for SearchService and SearchController, and security and integration tests
- Quote Surefire argLine in pom.xml to prevent JVM agent path-splitting on paths with spaces

Signed-off-by: Vicky Patel <vickybiz55808@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FEATURE: Implement Search End point

1 participant