Skip to content

Conversation

@ranuka-laksika
Copy link

@ranuka-laksika ranuka-laksika commented Nov 12, 2025

Fixes wso2/api-manager#3724 (comment)

Issue URL:wso2/api-manager#3724 (comment)

Problem

Publisher portal shows an incorrect validation message "URL should not be empty" when creating a GraphQL API with an Endpoint, even when the user has entered a valid domain name (e.g., "countries.trevorblades.com").

Root Cause

The validateURL function in ProvideGraphQL.jsx uses APIValidation.url.required().validate() which requires a full URL with http:// or https:// scheme. When users enter just a domain name, this strict URL validation fails and displays the misleading "URL should not be empty" message.

Solution

Modified the validation logic in ProvideGraphQL.jsx (line 196-216) to:

  • For GraphQL Endpoint: Skip strict URL validation and only check if the input is not empty
  • For GraphQL SDL URL: Keep the strict URL validation as before
  • Let the backend API validation handle the actual endpoint validation through introspection

Changes Made

  • Modified: portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/Steps/ProvideGraphQL.jsx
  • Added conditional validation based on input type (ENDPOINT vs URL)
  • Allows domain names without protocol for GraphQL Endpoint

Build Information

  • Java 11 (Temurin-Hotspot)
  • Maven 3.6.3
  • Built component: Publisher portal
  • Generated artifact: target/publisher.war

Artifacts Replaced

  • Frontend: Replaced publisher folder in wso2am-4.6.0/repository/deployment/server/webapps/
  • Unzipped publisher.war to create updated folder structure

Testing

No testing required for frontend changes (as per workflow guidelines)

Modified wso2am Pack Download

The complete modified wso2am-4.6.0 pack is available as a GitHub Actions artifact.

🔗 Download from GitHub Actions

Artifact Details:

  • Name: wso2am-4.6.0-issue-68.zip
  • How to Download:
    1. Click the link above
    2. Scroll to "Artifacts" section
    3. Download the zip file
    4. Extract and use directly

Contents: Complete wso2am pack with all updated artifacts ready to use.

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

Summary by CodeRabbit

  • Bug Fixes
    • GraphQL endpoint validation now supports flexible endpoint formats, including domain-like entries without requiring full URL formatting with protocol specifications
    • Improved error messaging provides clearer feedback when GraphQL endpoint values are empty

- Modified ProvideGraphQL.jsx to skip strict URL validation for GraphQL Endpoint
- Allows domain names without protocol (e.g., countries.trevorblades.com)
- Backend API validation will handle endpoint validation
- Fixes issue where users saw 'URL should not be empty' for valid domain inputs

Fixes #68
@coderabbitai
Copy link

coderabbitai bot commented Nov 12, 2025

Walkthrough

The change modifies the validateURL function in ProvideGraphQL.jsx to conditionally validate GraphQL endpoints based on input type. For ENDPOINT types, strict URL validation is bypassed, allowing domain-like values without protocols. For other types, standard URL validation is retained. Error messaging is adjusted to specify "GraphQL Endpoint should not be empty" for ENDPOINT type validation failures.

Changes

Cohort / File(s) Change Summary
GraphQL endpoint validation logic
portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/Steps/ProvideGraphQL.jsx
Modified validateURL function to conditionally apply URL validation based on inputType. ENDPOINT type skips strict validation and allows domain-like values; other types retain APIValidation.url.required() validation. Adjusted error messaging for ENDPOINT type validation failures.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as User Input
    participant ValidateURL as validateURL()
    participant Validation as APIValidation
    participant Debounce as debouncedValidateURLOrEndpoint

    rect rgb(200, 240, 220)
    Note over ValidateURL: New: ENDPOINT Type Path
    User->>ValidateURL: Input value, inputType="ENDPOINT"
    alt value is empty
        ValidateURL->>ValidateURL: Set error: "GraphQL Endpoint<br/>should not be empty"
        ValidateURL->>User: onValidate(false)
    else value is not empty
        ValidateURL->>Debounce: Trigger debounced validation
        Debounce->>User: Proceed with validation
    end
    end

    rect rgb(220, 235, 245)
    Note over ValidateURL: Existing: Other Input Types
    User->>ValidateURL: Input value, inputType≠"ENDPOINT"
    ValidateURL->>Validation: APIValidation.url.required().validate(value)
    alt validation succeeds
        Validation->>Debounce: Trigger debounced validation
    else validation fails
        Validation->>ValidateURL: Return error
        ValidateURL->>User: Update validity, onValidate(false)
    end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Focus areas:
    • Verify conditional logic correctly distinguishes between ENDPOINT and other input types
    • Confirm error message "GraphQL Endpoint should not be empty" aligns with UI requirements
    • Validate that debounced validation is properly triggered for non-empty ENDPOINT values
    • Check that existing URL validation for other input types remains functionally unchanged

Poem

🐰 A rabbit hops through endpoint lands,
Where protocols need not take a stand,
Domain-like values now find their way,
No strict URL rules hold sway,
Validation flows with flexible grace! ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR only addresses validation message removal for GraphQL Endpoint input, but linked issue #3724 requires fixing operation-level rate limiting UI behavior and preventing API save without throttling policies. Address all coding requirements from issue #3724: disable operation-level rate limiting dropdowns when API-level is selected, and prevent API save without API-level policy selection.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title directly addresses the main change: removing incorrect validation message for GraphQL Endpoint input by allowing domain names without protocol.
Out of Scope Changes check ✅ Passed The change to ProvideGraphQL.jsx validation logic is directly scoped to the stated objective of fixing the GraphQL Endpoint validation message issue.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide custom instructions to shape the summary (bullet lists, tables, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example:

"Create a concise high-level summary as a bullet-point list. Then include a Markdown table showing lines added and removed by each contributing author."


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9eea9b0 and a7c9cc6.

📒 Files selected for processing (1)
  • portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/Steps/ProvideGraphQL.jsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/Steps/ProvideGraphQL.jsx (2)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/ApiCreateGraphQL.jsx (1)
  • apiInputs (117-124)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/OpenAPI/Steps/ProvideOpenAPI.jsx (2)
  • apiInputs (82-82)
  • isValid (85-85)
🔇 Additional comments (1)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/Steps/ProvideGraphQL.jsx (1)

407-443: Backend validation behavior must be verified with the API service team.

The frontend offloads GraphQL endpoint validation to a separate backend service (via validateGraphQL() API call with useIntrospection: true). This backend code is not present in the repository. Before merging, confirm with the backend API team that the validation service correctly handles:

  • Domain-only endpoints (e.g., countries.trevorblades.com)
  • Endpoints with custom ports (e.g., example.com:8080)
  • Endpoints with/without protocol prefixes
  • Appropriate error messages for invalid formats

Check the backend API specification or service documentation to verify these scenarios are supported.

Comment on lines 196 to 216
function validateURL(value) {
const state = APIValidation.url.required().validate(value).error;
if (state === null) {
setIsValidating(true);
debouncedValidateURLOrEndpoint(apiInputs.inputValue);
// For GraphQL Endpoint, skip strict URL validation and allow domain names without protocol
if (inputType === ProvideGraphQL.INPUT_TYPES.ENDPOINT) {
if (value && value.trim() !== '') {
setIsValidating(true);
debouncedValidateURLOrEndpoint(apiInputs.inputValue);
} else {
setValidity({ ...isValid, url: { message: 'GraphQL Endpoint should not be empty' } });
onValidate(false);
}
} else {
setValidity({ ...isValid, url: state });
onValidate(false);
const state = APIValidation.url.required().validate(value).error;
if (state === null) {
setIsValidating(true);
debouncedValidateURLOrEndpoint(apiInputs.inputValue);
} else {
setValidity({ ...isValid, url: state });
onValidate(false);
}
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix parameter usage: validate the passed value, not stale state.

The conditional validation logic correctly addresses the reported issue by allowing domain names for GraphQL Endpoints. However, there's a significant concern with parameter usage:

Issue: Lines 201 and 210 pass apiInputs.inputValue to debouncedValidateURLOrEndpoint, but the function receives value as a parameter from the blur event (lines 390, 428). Since onChange updates apiInputs.inputValue asynchronously and onBlur fires immediately after, there's a potential race condition where the state hasn't been updated yet, causing validation of a stale value rather than what the user just entered.

Solution: Use the value parameter consistently throughout the function.

Apply this diff:

     function validateURL(value) {
         // For GraphQL Endpoint, skip strict URL validation and allow domain names without protocol
         if (inputType === ProvideGraphQL.INPUT_TYPES.ENDPOINT) {
             if (value && value.trim() !== '') {
                 setIsValidating(true);
-                debouncedValidateURLOrEndpoint(apiInputs.inputValue);
+                debouncedValidateURLOrEndpoint(value);
             } else {
                 setValidity({ ...isValid, url: { message: 'GraphQL Endpoint should not be empty' } });
                 onValidate(false);
             }
         } else {
             const state = APIValidation.url.required().validate(value).error;
             if (state === null) {
                 setIsValidating(true);
-                debouncedValidateURLOrEndpoint(apiInputs.inputValue);
+                debouncedValidateURLOrEndpoint(value);
             } else {
                 setValidity({ ...isValid, url: state });
                 onValidate(false);
             }
         }
     }

Minor note: Storing endpoint validation state in isValid.url (line 203) works functionally but is semantically confusing. Consider using a more generic key like isValid.input or isValid.value in a future refactor.

📝 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
function validateURL(value) {
const state = APIValidation.url.required().validate(value).error;
if (state === null) {
setIsValidating(true);
debouncedValidateURLOrEndpoint(apiInputs.inputValue);
// For GraphQL Endpoint, skip strict URL validation and allow domain names without protocol
if (inputType === ProvideGraphQL.INPUT_TYPES.ENDPOINT) {
if (value && value.trim() !== '') {
setIsValidating(true);
debouncedValidateURLOrEndpoint(apiInputs.inputValue);
} else {
setValidity({ ...isValid, url: { message: 'GraphQL Endpoint should not be empty' } });
onValidate(false);
}
} else {
setValidity({ ...isValid, url: state });
onValidate(false);
const state = APIValidation.url.required().validate(value).error;
if (state === null) {
setIsValidating(true);
debouncedValidateURLOrEndpoint(apiInputs.inputValue);
} else {
setValidity({ ...isValid, url: state });
onValidate(false);
}
}
}
function validateURL(value) {
// For GraphQL Endpoint, skip strict URL validation and allow domain names without protocol
if (inputType === ProvideGraphQL.INPUT_TYPES.ENDPOINT) {
if (value && value.trim() !== '') {
setIsValidating(true);
debouncedValidateURLOrEndpoint(value);
} else {
setValidity({ ...isValid, url: { message: 'GraphQL Endpoint should not be empty' } });
onValidate(false);
}
} else {
const state = APIValidation.url.required().validate(value).error;
if (state === null) {
setIsValidating(true);
debouncedValidateURLOrEndpoint(value);
} else {
setValidity({ ...isValid, url: state });
onValidate(false);
}
}
}
🤖 Prompt for AI Agents
In
portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/GraphQL/Steps/ProvideGraphQL.jsx
around lines 196 to 216, the function validateURL uses apiInputs.inputValue when
calling debouncedValidateURLOrEndpoint, which can validate a stale value due to
async state updates; change those calls to pass the local parameter value
instead (i.e., call debouncedValidateURLOrEndpoint(value)) so the blur handler
validates the exact input passed in; keep the existing setIsValidating,
setValidity and onValidate behavior unchanged.

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.

[UI] Multiple UI issues related to GraphQL APIs

1 participant