@@ -34,6 +34,7 @@ public class DefaultHttpResponseFormatter : IHttpResponseFormatter
3434 private readonly FormatInfo _eventStreamFormat ;
3535 private readonly FormatInfo _jsonLinesFormat ;
3636 private readonly FormatInfo _legacyFormat ;
37+ private readonly bool _isLegacyTransport ;
3738 private readonly IncrementalDeliveryFormat _incrementalDeliveryDefaultFormat ;
3839
3940 /// <summary>
@@ -122,7 +123,8 @@ public DefaultHttpResponseFormatter(
122123 ContentType . JsonLines ,
123124 ResponseContentType . JsonLines ,
124125 jsonLinesResultFormatter ) ;
125- _defaultFormat = options . HttpTransportVersion is HttpTransportVersion . Legacy
126+ _isLegacyTransport = options . HttpTransportVersion is HttpTransportVersion . Legacy ;
127+ _defaultFormat = _isLegacyTransport
126128 ? _legacyFormat
127129 : _graphqlResponseFormat ;
128130
@@ -400,11 +402,23 @@ protected virtual HttpStatusCode OnDetermineStatusCode(
400402 FormatInfo format ,
401403 HttpStatusCode ? proposedStatusCode )
402404 {
403- // the current spec proposal strongly recommends to always return OK
404- // when using the legacy application/json response content-type.
405405 if ( format . Kind is ResponseContentType . Json )
406406 {
407- return HttpStatusCode . OK ;
407+ // the legacy transport preserves the pre-spec behavior of always returning
408+ // 200 for the application/json response content-type.
409+ if ( _isLegacyTransport )
410+ {
411+ return HttpStatusCode . OK ;
412+ }
413+
414+ // per graphql-over-http §6.4.1, the application/json response content-type
415+ // should return 200 for every well-formed request regardless of errors
416+ // raised. the only 4xx is 400 for requests the server cannot interpret
417+ // (§6.4.1.1.1 JSON parse, §6.4.1.1.2 invalid parameters). honor a proposed
418+ // 400; everything else, including an unexpected 500, stays 200.
419+ return proposedStatusCode is HttpStatusCode . BadRequest
420+ ? HttpStatusCode . BadRequest
421+ : HttpStatusCode . OK ;
408422 }
409423
410424 // if we are sending a single result with the multipart/mixed header or
0 commit comments