skip to Main Content

I want to find and validates dynamic path variable.

User can enter url and dynamic path variable in input box like below.

http://localhost:3000/{abc}
https://google.com/{a}/{bb}/{ccc}

Dynamic path variable is optional. Therefore url that does not have path variable is also fine.

However, if user wants to add dynamic path variable, it must start with ‘/{‘ and ends with ‘}’.

Therefore urls below are not valid.

https://google.com/{}
https://helloWorld/{aaa
http://localhost:3000/aaa}
http://localhost:9999/{aaa}}

Here is what I did.

first I split url using ‘/’ and create a new array starts from 3rd index to the last index.

const url = 'https://google.com/{a}/{bb}/{ccc'

const splitUrl = url.split('/') // ['https:', '', 'google.com', '{a}', '{bb}', '{ccc']

const pathVaraibles = splitUrl.slice(3) // ['{a}', '{bb}', '{ccc']

Then I just need to check pathVariables array whether all elements in the array are valid variables.

Could this be the proper way to validate dynamic path variables in url?

2

Answers


  1. You can try the following way:

    function isValidUrlWithPathVariable(url) {
      const splitUrl = url.split('/');
    
      const pathVariables = splitUrl.slice(3).filter(i=>i);
      if (pathVariables.length === 0) {
        //URL does not have any path variables, which is valid
        return true;
      }
      const regex = /^{[^{}]+}$/;
      //check all the path variables against the regex
      for (let i = 0; i < pathVariables.length; i++) {
        if (!regex.test(pathVariables[i])) {
          return false;
        }
      }
    
      return true;
    }
    
    
    const urlValid1 = 'https://google.com';
    const urlValid2 = 'http://localhost:3000/{aaa}';
    console.log(isValidUrlWithPathVariable(urlValid1));  //true
    console.log(isValidUrlWithPathVariable(urlValid2));  //true
    
    const urlInvalid1 = 'https://google.com/{}';
    const urlInvalid2 = 'https://helloWorld/{aaa';
    const urlInvalid3 = 'http://localhost:3000/aaa}';
    const urlInvalid4 = 'http://localhost:9999/{aaa}}';
    console.log(isValidUrlWithPathVariable(urlInvalid1));//false
    console.log(isValidUrlWithPathVariable(urlInvalid2));//false
    console.log(isValidUrlWithPathVariable(urlInvalid3));//false
    console.log(isValidUrlWithPathVariable(urlInvalid4));//false
    Login or Signup to reply.
  2. If any of these assumptions are incorrect, you’ll have to adjust the final regular expressions. Everything depends a bit on what you’re ultimately trying to do.

    Are you trying to validate the URLs as well, or are we just assuming they’re valid & only want to look at the dynamic component? If so, that’s covered well in this SO question: What is the best regular expression to check if a string is a valid URL?.

    Secondly, what if we have a URL of the form: https://website.com/User/{userid}/Profile: Is this a valid dynamic URL? I’m going to assume, "yes", but all examples "end with" the dynamic portion.

    Thirdly, the dynamic strings you’re using are of the form {aaa}, {abc}, etc. but you didn’t really put any restrictions on them in the question. I’d assume "alphabetic" or "alphanumeric" but obviously other people have assumed they can be "anything that’s not a curly brace" (i.e. [^{}]+ in a regex is "one or more elements + that aren’t in the set [^] containing the values {}.")

    Are you always using "fully qualified URLs" or can they also be "root relative"? E.g. https://localhost:3010/User/Profile/{userid} vs /User/Profile/{userid}. I’m assuming fully qualified, but there’s benefits to using relative URLs in an app.


    I’d definitely use a similar approach to @Mamun’s answer and use a regular expression (regex) as well.

    Leveraging the fact that, "…curly braces are unsafe characters, and are not valid in URIs…" I’d just:

    • Validate that the URL matches your expected form with a very basic check,
    • Use a slightly different regex to extract the path variables,
    • (Run whatever your code would be to dynamically replace those vars),
    • Run a final regex over the URL to determine it’s valid (or just "use it" & trust nothing’s gone awry).
    // Starts with "http(s)://" then skips to the first "/"
    // Checks it's either: /{<alphanumeric>} (e.g. /{abc})
    // Or path component doesn't have `{}` in it at all (e.g. /Profile)
    // * Repeat 0 or more times (e.g. http://a.com OR https://b.com/{a}/{b}/Test/{c}/)
    function isDynamicUrl(url) {
        const testUrlRegex = /https*://[^/]+(/({w+})|([^{}]*))*?$/
        return testUrlRegex.test(url)
    }
    
    // Variables pulled from "somewhere"
    const props = {
        userId: 5,
        area: "Designs",
    }
    
    const path = "https://example.com/{userId}/{area}/Index"
    var url = ""
    
    // matches will be of the form: [["/{userId}", "userId"], ["/{area}", "area"]]
    if (isDynamicUrl(path)) {
        const replacementRegex = //{(w+)}/g;
        url = path.replace(replacementRegex, (match, group1) => "/" + props[group1])
    }
    
    // url == "https://example.com/5/Designs/Index"
    console.log(url)

    For testing regular expressions, I’d recommend a site like https://regexr.com/ which freely lets you test an expression against a block of text to validate it. If you paste my expression into a site like that, it’ll give a clearer explanation of how it works than I could probably describe.

    You may need to make some small changes for testing there, e.g. I used multiple lines so I had to use the /gm flag (anchors like $ will respect newlines) & also account for n (newline) when testing:
    /(https*://[^/n])(/([^{}n])|({w+}))*?$/gm

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search