Unable to get rewrite working

Hi there!

I have tried countless times, but to no avail. I’m trying to get a simple rewrite working, but the docs section on url rewrite are a bit thin and more examples would be great.

First off, the regex syntax doesn’t seem quite right and I’m not sure if I’m doing it correctly. I’m an old Perl guy who’s done a TON of regexes, and something like this:

“match_pattern”: “(w+)/(w+)”,

Seems to me ought to be:

“match_pattern”: “(\w+)/(\w+)”

But maybe your regex engine is different.

Anyhow,this is what I have:

“listen_path”: “/rest/”,
“target_url”: "http://some-service:6055

my app has two simple URLs, both for POST and GET:

/rest/application
/rest/some-otherthing

Tyk runs on port 8080, using k8s.

(note the hyphen/dash)

The underlying service is

/v1/application
/v1/some-otherthing

All I want to do is if someone goes to (example)

/rest/application

Go to the internal URL (target_url + the following)

/v1/application

I have tried:

“url_rewrites”: [{
“path”: “/rest/application/{id}”,
“method”: “GET”,
“match_pattern”: “/rest/application/(\w+)”,
“rewrite_to”: “/v1/application/$1”
},…

or

“match_pattern”: “/rest/application/(w+)”,

How can I do this?

Furthermore, how can I have it log specifically the rewrite and attempts to use the URL specified in the rewrite?

Thanks!

Hi Patrick,

a similar issue has been resolved in this ticket.

I hope this helps.

Thanks,
Kos @ Tyk Support Team

The issue is that you have /rest at the start of the match patterns and parhs, you can probably do without that since it is ignored.

I tend to test the regex on regexr and they tend to work.

You can track the endpoint analytics by setting it as a tracked URL in the endpoint designer from the plugins drop down.

There’s no selective logging though I’m afraid, it’s all or nothing.

q1: If I have a path /patha/pathb/pathc and I merely want to transform pathb/pathc to something, can I just specify the part of the path that I want? For instance, say I wanted to just specify only “pathc”, would that work?

q2: is the rewrite assumed to rewrite to the internal host/port and service yet not require having to specify any of the host/port of that service since I already have target_url defined?

q3: Is it (\w+) or is it (w+) ?

Thank you!

Inbound: /patha/pathb/pathc
Path: /patha/pathb/{p2}
Match: \/patha\/pathb\/(\w+)
Rewrite: /patha/pathb/?pathc_val=$1

The {p1} variables are actually wildcards, they are to make the path readable and actually convert internally to a wide match ((.*)), it’s for human readability. You can also use regexes in the path if necessary., but it’s not recommended.

Don;t specify a host or port, but you can if you want to redirect the request to a new domain, just add a new host/port:

Inbound: /patha/pathb/pathc
Path: /patha/pathb/{p2}
Match: \/patha\/pathb\/(\w+)
Rewrite: http://myothertarget.com:12345/patha/pathb/?pathc_val=$1

(\w+)

regexr.com generates valid regexes you can cut and paste into the designer.

Thanks!

Once I get this working, how might I contribute documentation modifications and/or examples to your docs?

Hi Patrick,

there is a Suggest Edit hyperlink on each section. You can send us your suggestion via that form and we will consider it.

Thanks,
Kos @ Tyk Support Team

So, more fun.

I get an error when I use (\w+) that I thought was some other issue before, but the only way around it is to use “(\w+)”. This is because the way we do this is basically we have kubernetes and an init container that submits the api spec (json) against a tyk pod/service.

But I still can’t get this working.

I even just tried:

“url_rewrites”: [{
“path”: “application”,
“method”: “GET”,
“match_pattern”: “application”,
“rewrite_to”: “v1/application”
},{

if the URL has “application” in it, this should work, right?

Question: you said before that “/rest” would be ignored. Is this because I have it set as “listen_path”?

time=“May 8 15:16:33” level=error msg=“Couldn’t decode new API Definition object: invalid character ‘w’ in string escape code”

This is using “(\w+)”

Hi Patrick,

can you share your full API definition ?

Thanks,
Kos @ Tyk Support Team

-- tyk.json:
{
  "name": "my-service",
  "api_id": "my-service",
  "org_id": "abcdefg12345",
  "definition": {
      "location": "",
      "key": ""
  },
  "use_keyless": true,
  "auth": {
      "auth_header_name": ""
  },
  "version_data": {
      "not_versioned": true,
      "versions": {
          "Default": {
              "name": "Default",
              "expires": "3000-01-02 15:04",
              "use_extended_paths": true,
              "extended_paths": {
                  "ignored": [],
                  "white_list": [],
                  "black_list": [],
                  "url_rewrites": [{
                      "path": "/rest/{op}/{id}",
                      "method": "GET",
                      "match_pattern": "\/rest\/(\w+)\/(\w+)",
                      "rewrite_to": "v1/$1/$2"
                  },{
                      "path": "/rest/{op}",
                      "method": "POST",
                      "match_pattern": "\/rest\/(\w+)"
                      "rewrite_to": "v1/$1"
                  }]
              }
          }
      }
  },
  "proxy": {
      "listen_path": "/rest/",
      "target_url": "http://patg-cnf-my-service.patg:1234",
      "strip_listen_path": true
  },
  "do_not_track": true
}-- end tyk.json

auth=x-tyk-authorization:xxxxx
curl -XDELETE -L -H x-tyk-authorization:xxxxx http://tyk.patg:8080/tyk/apis/my-service -Ss -k
{"status":"error","error":"Delete failed"}

curl -L -H x-tyk-authorization:xxxxx http://tyk.patg:8080/tyk/reload/ -Ss -k
{"status":"ok","error":""}

curl -XPUT -w '\nresponse_code=%{http_code}\n' -L -H x-tyk-authorization:xxxxx http://tyk.patg:8080/tyk/apis/my-service -d @/etc/tyk/api/tyk.json -Ss -k
{"status":"error","error":"Request malformed"} response_code=400
Error: command failed

Hi Patrick,

Is worth to check if the JSON is valid, which in your case is not. JSONLint validator is what I use .
So you may try "match_pattern": "\\/rest\\/(\\w+)\\/(\\w+)" and "match_pattern": "\\/rest\\/(\\w+)" .

Also your curl command is slightly wrong, you don’t need to inject the api_name to your request. So you would need something like curl -v -H "x-tyk-authorization: xxxxxxxx" -s -H "Content-Type: application/json" -X POST -d @your-file.json http://localhost:8080/tyk/apis/

Let me know if you need any further assistance.

Thanks,
Kos @ Tyk Support Team

Got it working!

Thank you - it’s all about escaping back-slash.

I’ll submit some edits for your docs as well as my example.

2 Likes