-2
\$\begingroup\$

The code is not efficient, let's say the url matched in the first regex case but I'm still evaluating second regex for the second case while knowing it's mutually exclusive and only one of them will be true. The efficiency will further lower if I add more urls to match against.

Also is there a way without introducing another boolean variable to eloquently handle these cases?

public void service(ServiceRequest serviceRequest, ServiceProxy serviceProxy) {
    HttpRequest request = serviceRequest.HttpRequest;
    HttpResponse response = serviceRequest.HttpResponse;

    Match match;
    bool found = false;

    match = Regex.Match(request.Path.Value, @"/articles/(\d+)/thumbnail"); // case "/articles/:id/thumbnail":
    if(match.Success) {
        found = match.Success;
        if(request.Method.Equals(HttpMethod.Get.ToString())) {
            serviceRequest.Params.Add("id", match.Groups[1].Value);
            serviceRequest.ResultData = serviceProxy.GetArticleThumbnail(serviceRequest);
        } else {
            throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
        }
    }

    match = Regex.Match(request.Path.Value, @"/leads/(\d+)/collections/(.*)"); // case "/leads/:id/collections/:entityName": // share
    if(match.Success) { 
        found = match.Success;
        if(request.Method.Equals(HttpMethod.Put.ToString())) {
            serviceRequest.Params.Add("id", match.Groups[1].Value);
            serviceRequest.Params.Add("entityName", match.Groups[2].Value);
            serviceRequest.ResultData = serviceProxy.ShareCollection(serviceRequest);
        } else {
            throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
        }   
    }

    if(!found) throw new HttpException(HttpStatusCode.NotFound, "Not Found"); // default case
}
\$\endgroup\$
3
  • \$\begingroup\$ also the code is not efficient, let's say the url matched in the first regex case but I'm still evaluating second regex for the second case while knowing it's mutually exclusive and only one of them will be true. The efficiency will further lower if I add more urls to match against. \$\endgroup\$ Commented Mar 14, 2018 at 9:36
  • \$\begingroup\$ why are you writing a custom router instead of using existing ones? \$\endgroup\$ Commented Mar 14, 2018 at 14:47
  • \$\begingroup\$ because i'm using a custom mvc framework that was designed around GoF patterns, it's platform and language agnostic for both client and server in different languages, so router is something that comes with native mvc frameworks like asp.net mvc, that's why I don't have a router. \$\endgroup\$ Commented Mar 14, 2018 at 16:14

2 Answers 2

-1
\$\begingroup\$

Added if else branching structure using to avoid repeating regex's.

Match match = Regex.Match(request.Path.Value, @"/articles/(\d+)/thumbnail"); // case "/articles/:id/thumbnail":
if(match.Success) {
    if(request.Method.Equals(HttpMethod.Get.ToString())) {
        serviceRequest.Params.Add("id", match.Groups[1].Value);
        serviceRequest.ResultData = serviceProxy.GetArticleThumbnail(serviceRequest);
    } else {
        throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
    }
} else if ((match = Regex.Match(request.Path.Value, @"/leads/(\d+)/collections/(.*)")) != null && match.Success) {
    if(request.Method.Equals(HttpMethod.Put.ToString())) {
        serviceRequest.Params.Add("id", match.Groups[1].Value);
        serviceRequest.Params.Add("entityName", match.Groups[2].Value);
        serviceRequest.ResultData = serviceProxy.ShareCollection(serviceRequest);
    } else {
        throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
    }
} else {
    throw new HttpException(HttpStatusCode.NotFound, "Not Found"); // none of the cases above
}
\$\endgroup\$
7
  • 1
    \$\begingroup\$ found could never be true in the else if. \$\endgroup\$ Commented Mar 14, 2018 at 10:52
  • \$\begingroup\$ found will get true in line #6 once a match is successful \$\endgroup\$ Commented Mar 14, 2018 at 10:53
  • 1
    \$\begingroup\$ Nope. if match.Success == true it will never execute the else if. This is basic coding knowledge. \$\endgroup\$ Commented Mar 14, 2018 at 10:58
  • \$\begingroup\$ you are right, I took another approach, please review. \$\endgroup\$ Commented Mar 14, 2018 at 11:08
  • 4
    \$\begingroup\$ @Developer11 You can answer your own questions, however please only do so if you can provide a full answer, i. e. a full review of your own code (which is not common because as the author of the code you usually seek feedback from others). In this case it does not look as if you intended to answer it, so please remove the answer and add the information to the question instead, if needed. Note that you should not change your question's code to include suggestions from comments or answers. \$\endgroup\$ Commented Mar 14, 2018 at 11:08
-1
\$\begingroup\$

In your own answer you already suggested the use of if - else if - else, but I find the way you wrote the conditions quite hard to read. Instead I suggest to save the matches in different variables, rather than overwriting the same variable.

Match matchThumbnail = Regex.Match(request.Path.Value, @"/articles/(\d+)/thumbnail");
Match matchCollections = Regex.Match(request.Path.Value, @"/leads/(\d+)/collections/(.*)");

This way, you can use them in the if-conditions without the risk of confusing the values due to them sharing the same variable name:

if (matchThumbnail.Success)
{
    // ...
}
else if (matchCollections.Success)
{
    // ...
}
else
{
    throw new HttpException(HttpStatusCode.NotFound, "Not Found");
}

For the exception condition, you can now use both in one condition. In your own answer, I think you might have a bug since when the first match is successful, the second one is not checked due to the else-if. (Edit: You commented that the regular expressions are mutually exclusive, so I changed the above to an if - else if - else.


I recommend using the C#-typical bracing style:

if (something)
{
    // Code
}

instead of

if (something) {
    // Code
}

Also I suggest using braces even for oneliners, as in the last line of your code. Even then I would use the bracing style shown above, but if you want to make a one-liner, putting braces within the same line makes it still more readable:

if (something) { // Code }

instead of

if (something) // Code

In C# the preferred way of checking string equality is using == instead of myString.Equals("");.

if (request.Method == HttpMethod.Get.ToString())

is usually considered more readable than

if(request.Method.Equals(HttpMethod.Get.ToString()))

// case "/articles/:id/thumbnail":

// default case

These comments do not add much information that is not already in the code, so they are redundant.

// case "/leads/:id/collections/:entityName": // share

The same applies here, however that // share is even confusing, as it is not obvious to me what it is supposed to tell about the code, and the comment in a comment is also weird. Maybe it was on a different line before.

In general I recommend writing comments in plain english on their own line before the code they are refering to.

\$\endgroup\$
4
  • \$\begingroup\$ 1. executing both regular expressions is what I was avoiding at the first place to begin with which is not efficient. \$\endgroup\$ Commented Mar 14, 2018 at 16:02
  • \$\begingroup\$ 2. "you might have a bug since when the first match is successful, the second one is not checked". My URL's are mutually exclusive, if you have matched one condition, there's no need to check the other \$\endgroup\$ Commented Mar 14, 2018 at 16:03
  • \$\begingroup\$ 3. Thanks for your tips on String.Equals and comments \$\endgroup\$ Commented Mar 14, 2018 at 16:04
  • \$\begingroup\$ Made some changes to accomodate that information. \$\endgroup\$ Commented Mar 16, 2018 at 8:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.