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

Pact consumer API is incompatible with the Refit client #424

Closed
lehmamic opened this issue Nov 9, 2022 · 8 comments
Closed

Pact consumer API is incompatible with the Refit client #424

lehmamic opened this issue Nov 9, 2022 · 8 comments

Comments

@lehmamic
Copy link

lehmamic commented Nov 9, 2022

Hi there,

We are using Refit to generate typed API clients.

e.g.

var httpClient = new HttpClient { BaseAddress = new Uri(ctx.MockServerUri, "/api") };
var client = Refit.RestService.For<IMyApiClient>(httpClient);

When I do a GET request with Refit, it will send a request with an empty body without any content-type header. Pact expects a missing body in this case. When I try to configure an expected empty body (with WithBody) to match it with the request Refit is doing, I am forced to set an expected content-type as well. With this constraint I can never make those two library work together.

2022-11-09T07:00:43.297948Z  INFO tokio-runtime-worker pact_mock_server::hyper_server: Received request HTTP Request ( method: GET, path: /api/s2s/users, query: Some({"UserIds": ["1,2,3"]}), headers: Some({"host": ["127.0.0.1:62466"], "request-id": ["|98394da7c0defc2670305f8a0e803693.040a6b8dbc244591."], "authorization": ["Any valid token"], "accept": ["application/json"], "traceparent": ["00-98394da7c0defc2670305f8a0e803693-040a6b8dbc244591-00"]}), body: Empty )
2022-11-09T07:00:43.298541Z  INFO tokio-runtime-worker pact_matching: comparing to expected HTTP Request ( method: GET, path: /api/s2s/users, query: Some({"UserIds": ["1,2,3"]}), headers: Some({"host": ["127.0.0.1:56541"], "request-id": ["|b7d5eb21662c741f992816792949f208.34ac459fb07586a2."], "accept": ["application/json"], "Authorization": ["Bearer SomeValidAuthToken"], "traceparent": ["00-b7d5eb21662c741f992816792949f208-34ac459fb07586a2-00"]}), body: Missing )

@mefellows
Copy link
Member

Why does it send an empty body? Bodies on GET requests are not supposed to be a thing (especially if not requested by the client)

@lehmamic
Copy link
Author

lehmamic commented Nov 9, 2022

You ask questions ^^ I don't know why they are doing that. I was supprised myself when I detected the different handling between Pact and Refit.

@mefellows
Copy link
Member

@uglyog any thoughts/suggestions on how we could address this use case?

@rholshausen
Copy link

The FFI functions need to be updated to support passing in an empty body and content type

@lehmamic
Copy link
Author

The FFI functions need to be updated to support passing in an empty body and content type

Another option would be that no body considers an empty body as well. Either way is ok.

Btw. I used this combination already before and it did not cause any problems. But this was with Pact V2.

@lehmamic
Copy link
Author

lehmamic commented Nov 15, 2022

I just tried it with a plain HttpClient. This sends Body: Empty as well. Am I doing something wrong?

    public async Task<ICollection<UserDto>> GetUsersAsync(GetUsersQueryParameters query, CancellationToken cancellationToken = default)
    {
        return (await _http.GetFromJsonAsync<ICollection<UserDto>>($"/users?UserIds={string.Join(",", query.UserIds)}", cancellationToken))!;
    }

My Pact definition:

        _pactBuilder!
            .UponReceiving("A GET request to retrieve multiple users with existing ids 1, 2 and 3")
            .Given("There exist a user for every provided id")
            .WithRequest(HttpMethod.Get, "/api/s2s/users")
                .WithQuery("UserIds", "1,2,3")
                .WithHeader("accept", "application/json")
                .WithHeader("host", Match.Type("127.0.0.1:56541"))
                .WithHeader("traceparent", Match.Type("00-b7d5eb21662c741f992816792949f208-34ac459fb07586a2-00"))
                .WithHeader("request-id", Match.Type("|b7d5eb21662c741f992816792949f208.34ac459fb07586a2."))
                .WithHeader("Authorization", Match.Type("Bearer SomeValidAuthToken"))
            .WillRespond()
                .WithStatus(HttpStatusCode.OK)
                .WithHeader("Content-Type", "application/json; charset=utf-8")
                .WithJsonBody(.....);

Driver logs:

INFO tokio-runtime-worker pact_mock_server::hyper_server: Received request HTTP Request ( method: GET, path: /api/s2s/users/, query: Some({"UserIds": ["1,2,3"]}), headers: Some({"authorization": ["SomeValidAuthToken"], "request-id": ["|7205c82ecb83af9975f68ea3da24236c.0d027876ee15c914."], "host": ["127.0.0.1:52322"], "traceparent": ["00-7205c82ecb83af9975f68ea3da24236c-0d027876ee15c914-00"], "accept": ["application/json"]}), body: Empty )
2022-11-15T07:00:20.329160Z  INFO tokio-runtime-worker pact_matching: comparing to expected HTTP Request ( method: GET, path: /api/s2s/users, query: Some({"UserIds": ["1,2,3"]}), headers: Some({"traceparent": ["00-b7d5eb21662c741f992816792949f208-34ac459fb07586a2-00"], "host": ["127.0.0.1:56541"], "accept": ["application/json"], "request-id": ["|b7d5eb21662c741f992816792949f208.34ac459fb07586a2."], "authorization": ["Bearer SomeValidAuthToken"]}), body: Missing )

@lehmamic
Copy link
Author

I figured out what the final problem was: #420

This issue can be closed

@mefellows
Copy link
Member

ah! 🤦

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