imposter icon indicating copy to clipboard operation
imposter copied to clipboard

How to set a basePath in the _config.yaml ?

Open hilsonp opened this issue 2 years ago • 6 comments

Hello,

We searched the doc and the issues but did not find the information.

  • We are mocking the myApi.v1 API (myApi.v1_config.yaml) which has a resource /resource
  • We are mocking the myApi.v2 API (myApi.v2_config.yaml) which has a resource /resource
  • We want to run a single Imposter (in recursive mode) to expose both mocks

Question: How to specify a base path in each _config.yaml in order to avoid a conflict between the two mocks: We would like:

  • The myApi.v1 API mock exposes http://my.imposter:1234/myApi.v1/resource
  • The myApi.v2 API mock exposes http://my.imposter:1234/myApi.v2/resource

Is that feasible ?

Thank you,

hilsonp avatar May 24 '23 08:05 hilsonp

To clarify my question, we are using the rest and soap plugins. We are not using the openapi plugin.

We would like to use one imposter instance with the recursive scan of config files to ease deployment and we need to control the basepath of our mock servers.

REST

We would like to be able to set the basepath that would prefix all resource path set in an imposter mock configuration Here would be an example that would let me access my api myApi.v1 with a GET http://my.imposter:1234/apis/myApi/v1/resource

plugin: rest
path: /apis/myApi/v1
resources:
  - method: GET
    path: "/resource"
    response:
      ...

This way, I can safely have ONE imposter instance (hence one port) expose 2 api featuring the exact same resource.

Note: Our current work-around is to prefix ALL resources path with the basepath but this is cumbersome.

SOAP

We would like to be able to overwrite the wsdl "soap:address location" basepath by a custom value of our choice.

I found out at io/gatehill/imposter/plugin/soap/SoapPluginImpl.kt:145 that I could set a 'path' that would prefix the "soap:address location" which is better than nothing but as we do not own the wsdl files and as the provider could change/update the "soap:address location" at anytime (impacting our ci/cd), we really would like to fully manage it (hence overwrite it).

Here would be an example that would let me make a SOAP request to myServiceV1 with a POST http://my.imposter:1234/services/myServiceV1 even if the wsdl has the following: <soap:address location="https://provider.address:5678/foo/barV1"/>

plugin: soap
wsdlFile: wsdl/myServiceV1.wsdl
path: /services/myServiceV1
resources:
  - operation: myOperation
    response:
      ...

Note: Our current work-around is to patch the wsdl file which is not great because those are not our files and we would like to keep them prestine.

Could you please help us by enabling a global 'path' or 'basePath' per '-config.yaml' file ?

hilsonp avatar Jun 08 '23 12:06 hilsonp

For REST, maybe (but I'm dumb) you could prepend config.path to route (if config.path.isNullOrEmpty()) at io.gatehill.imposter.plugin.rest.RestPluginImpl#addResourceHandler

        uniqueRoutes.forEach { (route, config) ->
            addResourceHandler(router, config, route)
        }

hilsonp avatar Jun 08 '23 13:06 hilsonp

My feature request still make sense (I think) but I wanted to let you know that we decided to run one imposter process per mock and this is therefore not a blocking point for us.

Thank you for the great project.

hilsonp avatar Jun 09 '23 08:06 hilsonp

Hi @hilsonp, in the latest beta version, there are a couple of things that could help here.

New basePath property

This can be set at the root configuration and applies to all paths in that configuration file.

Example:

plugin: rest
basePath: /example

resources:
- method: get
  path: /foo
  response:
    content: "Hello world"

This would result in the resource being accessible at the path: /example/foo.

Auto base path

When using recursive configuration discovery, you can automatically set the basePath based on the subdirectory path.

To enable this behaviour set the environment variable:

IMPOSTER_AUTO_BASE_PATH=true

If the directory structure was as follows:

<config root>
\-- mock1
|   \-- some-config.yaml
\-- mock2
|   \-- another-config.yaml
\-- nested
    \-- mock2
        \-- another-config.yaml

...then the basePath will be set as follows:

  • for 'mock1' it would be /mock1
  • for 'mock2' it would be /mock2
  • for 'mock3' it would be /nested/mock3

outofcoffee avatar Jun 11 '23 22:06 outofcoffee

Fantastic ! I'll give it a try !

hilsonp avatar Jun 12 '23 07:06 hilsonp

@outofcoffee

This message to confirm I tested both "basePath" and IMPOSTER_AUTO_BASE_PATH and they both work as expected.

It should be noted that if I create a mock

  • exposing the resource /res
  • in the directory /foo
  • and set "basePath: /bar" in its /foo/foo-configuration.yaml:

Launching "imposter up" with or without the -r option and without the IMPOSTER_AUTO_BASE_PATH=true will expose the ressources as: GET /bar/res

Launching "imposter up" with the -r option and with the IMPOSTER_AUTO_BASE_PATH=true will expose the ressources as: GET /foo/res

Some user may find it useful to have the resource exposed as follows when -r and IMPOSTER_AUTO_BASE_PATH=true are used with a basePath set: GET /foo/bar/res

Otherwise, I suggest, you specify in the doc that IMPOSTER_AUTO_BASE_PATH overwrite any basePath present in the configuration.

Best regards and thank you for this change.

We are still testing different approaches and may end up using the IMPOSTER_AUTO_BASE_PATH=true ;-)

hilsonp avatar Jul 17 '23 15:07 hilsonp