Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add support to recognise custom json media-types #211

Closed
alefranz opened this issue Oct 9, 2018 · 26 comments
Closed

Feature: Add support to recognise custom json media-types #211

alefranz opened this issue Oct 9, 2018 · 26 comments
Assignees

Comments

@alefranz
Copy link

alefranz commented Oct 9, 2018

Hi,

This is a feature request to add support to recognise as json custom media types:
e.g. application/vnd.*+json.

I think it could be either match on this pattern (or just +json) or open the BodyParser so it can be customized or media-types can be registered.

Specifically I'm after the ability to correctly save the payload as json when saving the auto generated mappings (when capturing as proxy).

If you are open to the idea I can contribute a PR for this.

@StefH StefH self-assigned this Oct 9, 2018
@StefH
Copy link
Collaborator

StefH commented Oct 9, 2018

Or define at the mapping that the request body should be parsed as String, Json or Bytes by using a new property at the body mapping named ParseBodyAs.

Using this new setting overrides the default Content-Type logic.

Example

{
    "Guid": "debaf408-3b23-4c04-9d18-ef1c020e79f3",
    "Request": {
        "Path": {
            "Matchers": [
                {
                    "Name": "WildcardMatcher",
                    "Pattern": "/jsonbodytest2",
                    "IgnoreCase": true
                }
            ]
        },
        "Methods": [
            "post"
        ],
        "Body": {
            "ParseBodyAs": "Json",
            "Matcher": {
                "Name": "JsonMatcher",
                "Pattern": {
                  "x": 42,
                  "s": "s"
                }
            }
        }
    },
    "Response": {
        "StatusCode": 200,
        "Body": "{ \"result\": \"jsonbodytest2\" }"
    }
}

@lesnes
Copy link

lesnes commented Oct 10, 2018

i am very interested in this new feature (ParseBodyAs). currently, BodyParser only supports parsing as string for certain content types. this means that one cannot use IStringMatcher implementations for matching request Body when content type is something like multipart/form-data.

when do you expect to release a new version to nuget that includes this functionality ? is it on a branch that i could take a look at?

@StefH
Copy link
Collaborator

StefH commented Oct 10, 2018

I'll take a look and start building this new functionality.

@lesnes
Copy link

lesnes commented Oct 10, 2018

that would be great, thanks!

@alefranz
Copy link
Author

@StefH is there a way to specify ParseBodyAs with the fluent syntax? and what about in the ProxyAndRecordSettings?

@StefH
Copy link
Collaborator

StefH commented Oct 10, 2018

Hello @lesnes and @alefranz,
I'm currently working on a PR #212 which updates the logic for the body parser.

In short:

  • Using a IStringMatcher will always work because the BodyAsString is always filled.
  • Using a IObjectMatcher like JsonMatcher, JsonPathMatcher and LinqMatcher will work in case it's a Json object

Please have a look to see if this will solve your questions.

@alefranz
Copy link
Author

In the current version I believe sometimes you only have the body as bytes.
Also matching a json with a string is often a pain as the sample response data for the mock are usually not minified, so in my scenario I still need the ability to change something in DetectBodyTypeFromContentType to be able to set custom media type as json.
Ideally would be nice for that class to not be static and the library support to extend it but that seems quite a lot of work. What about using a regex and testing against application/vnd\..*+json?

@StefH
Copy link
Collaborator

StefH commented Oct 10, 2018

The property DetectBodyTypeFromContentType is not really used in the logic, it's just for information.

The Content-Type is not used anymore in the logic now.

The real logic is done with the DetectedBodyType.

I can implement application/vnd\..*+json as a RegEx if you like, but the logic is not really used.

@alefranz
Copy link
Author

Ok, I guess I didn't really get the gist of the PR. I'll have a better look. Do you publish the PR builds as prerelease on myget by any chance?

@StefH
Copy link
Collaborator

StefH commented Oct 10, 2018

Added a preview version to MyGet
https://www.myget.org/F/wiremock-net/api/v3/index.json

@lesnes
Copy link

lesnes commented Oct 11, 2018

wow, that was quick. great job! looks like it would suit my purposes

@StefH
Copy link
Collaborator

StefH commented Oct 12, 2018

@lesnes
Copy link

lesnes commented Oct 14, 2018

i've tested my usage requirement for multipart/form-data against 1.0.4.18-ci-1343 and it is working now 👍

@StefH
Copy link
Collaborator

StefH commented Oct 14, 2018

Good news.

@alefranz : If you can confirm this issue and also the other issue; I can create a new official build.

@alefranz
Copy link
Author

alefranz commented Oct 14, 2018

Apologies, I will be able to test only on Monday.

@alefranz
Copy link
Author

alefranz commented Oct 15, 2018

Nice, now the mapping has the body as json, however when I save the mappings with SaveStaticMappings I end up with all 3 versions of it (text, json and binary) in the json.
It would be nice to define which format to save in SaveStaticMappings

@StefH
Copy link
Collaborator

StefH commented Oct 15, 2018

Ah, I did not think of that.
By default, the mapping should only be saved for the DetectedBodyType, just as it is now. I'll fix this and a new version should be automatically added to MyGet once it's ready.

Saving all 3 would be an additional option, which will be available in the next version.

@alefranz
Copy link
Author

but in my scenario with application/vnd.*+json what would be the DetectedBodyType?

@StefH
Copy link
Collaborator

StefH commented Oct 15, 2018

@alefranz
When I think about it again...

1]
The DetectBodyType will be be based on the body, not on content-type.

2]
The DetectBodyTypeFromContentType will be be based on the content-type, but it's not used in the logic.

3]
I think you mean /__admin/requests or RequestsGet() ? That code does indeed save all 3 versions:

"Body": "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }",
"BodyAsJson": {
	"things": [
		{
			"name": "RequiredThing"
		},
		{
			"name": "Wiremock"
		}
	]
},
"BodyAsBytes": "eyAidGhpbmdzIjogWyB7ICJuYW1lIjogIlJlcXVpcmVkVGhpbmciIH0sIHsgIm5hbWUiOiAiV2lyZW1vY2siIH0gXSB9",

This I can update.

@alefranz
Copy link
Author

alefranz commented Oct 15, 2018

This is my workflow:

  • I start the mock as proxy
ProxyAndRecordSettings = new ProxyAndRecordSettings
                {
                    Url = originaUrl,
                    SaveMapping = true,
                    SaveMappingToFile = false
                };
  • I execute my end to end flow
  • on shutdown I use SaveStaticMappings to save the generated mapping (which contains the proxied response) to a specific folder (as with SaveMappingToFile I can't specify a folder, but I have multiple mocks running so I need to separate those)

All this responses are json but I have custom media types application/vnd.*+json.

The purpose of this is to automatically generate the mappings to load in my tests.

My goal is to have only BodyAsJson in the saved mapping as it is the readable one.

@StefH
Copy link
Collaborator

StefH commented Oct 16, 2018

I see your point.
Can you try latest from the MyGet feed: 1.0.4.18-ci-1349 ?

See https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions for details on MyGet

@StefH StefH changed the title Add support to recognise custom json media-types Feature: Add support to recognise custom json media-types Oct 18, 2018
@StefH
Copy link
Collaborator

StefH commented Oct 23, 2018

@alefranz : did you have time to test the latest version on MyGet?

@alefranz
Copy link
Author

Apologies for the delay.

It works like a charm!

Thanks!

@StefH
Copy link
Collaborator

StefH commented Oct 24, 2018

@alefranz Are you sure you tested the 1.0.4.18-ci-1349 (or later) MyGet version ?

@alefranz
Copy link
Author

Yes, I've tested 1.0.4.18-ci-1349 and the saved mapping contains only the BodyAsJson as desired

@StefH StefH closed this as completed Oct 25, 2018
@alefranz
Copy link
Author

Thank you!

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

No branches or pull requests

3 participants