loopbackio / loopbackio/loopback-next

Unsupproted Media Type Error with application/json-patch+json

Offen
#7,617 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug REST
Vorherrschende Sprache
TypeScript
Sterne
5.1k
Forks
1.1k
Ø Merge
2 T. 21 Std.
Gemergte PRs (30 T.)
27

Beschreibung

Steps to reproduce

  1. Run application
  2. Send patch request with application/json-patch+json media type

Current Behavior

UnsupportedMediaTypeError: Content-type application/json-patch+json does not match [application/json]

Expected Behavior

I expect the application to accept application/json-patch+json media type

Link to reproduction sandbox

Work won't allow me to put code in sandbox.

Additional information

win32 x64 14.16.0
+-- @loopback/authentication@7.3.1
+-- @loopback/authentication-passport@3.2.1
+-- @loopback/boot@3.4.1
+-- @loopback/core@2.16.1
+-- @loopback/repository@3.7.0
+-- @loopback/rest@9.3.1
+-- @loopback/rest-explorer@3.3.1
+-- @loopback/security@0.5.1
+-- @loopback/service-proxy@3.2.1
+-- UNMET DEPENDENCY @opsdash/loopback-okta-auth@^0.0.1npm
+-- @raad/loopback-logging@2.0.1
+-- @raad/loopback-problems@1.0.1ERR! peer dep missing: eslint-plugin-spellcheck@^0.0.17, required by @raad/eslint-config-codestyle-typescript@5.0.5
npm+-- loopback-connector-mongodb@6.0.1
ERR! missing: @opsdash/loopback-okta-auth@^0.0.1, required by @opsdash/user-service@0.0.1

specific controller

  @patch('/users/me')
  @response(200, {
    description: 'User model instance',
    content: { 'application/json': { schema: getModelSchemaRef(User) } },
  })
  @authenticate(OKTA_AUTH_TOKEN_STRATEGY_NAME)
  async updateUser(
    @requestBody({
      description: 'User model instance',
      required: true,
      content: {
        'application/json-patch+json': {
          schema: {
            type: 'array',
            items: getModelSchemaRef(JsonPatch),
          },
        },
      },
    })
    patches: JsonPatch[],
  ): Promise<User> {
    let user = await this.userRepository.findOne({
      where: { key: this.userProfile.id },
    });

    if (!user) {
      throw new HttpErrors.NotFound();
    }

    await this.userRepository.jsonPatch(user, patches);

    user = await this.userRepository.findOne({
      where: { key: this.userProfile.id },
    });

    if (!user) {
      throw new HttpErrors.NotFound();
    }

    return user;
  }

JsonPatch model

import { Model, model, property } from '@loopback/repository';
import { JSONValue } from '@loopback/core';

@model()
export class JsonPatch extends Model {
  @property({
    type: 'string',
    required: true,
    jsonSchema: {
      enum: ['add', 'remove', 'replace', 'move', 'copy', 'test', '_get'],
    },
  })
  op: 'add' & 'remove' & 'replace' & 'move' & 'copy' & 'test' & '_get';

  @property({
    type: 'string',
    required: true,
  })
  path: string;

  @property({
    type: 'object',
  })
  value?: JSONValue;

  @property({
    type: 'string',
  })
  from?: string;

  constructor(data?: Partial<JsonPatch>) {
    super(data);
  }
}

export interface JsonPatchRelations {
  // describe navigational properties here
}

export type JsonPatchWithRelations = JsonPatch & JsonPatchRelations;

error stack

[2021-07-14T14:03:02.131Z] ERROR (UserService/4892 on CHRDEV42725):
    requestId: "RequestContext-QuzkmMDRTbiTuMkFzvMHAA-19"
    correlationId: "QuzkmMDRTbiTuMkFzvMHAA-20"
    event: "rest.sequence.actions.reject"
    err: {
      "type": "UnprocessableEntityError",
      "message": "The request body is invalid. See error object `details` property for more info.",
      "stack":
          UnprocessableEntityError: The request body is invalid. See error object `details` property for more info.
              at Object.invalidRequestBody (D:\Workspace\javascript\opsdash-services-test\opsdash-services\packages\user-service\node_modules\@loopback\rest\src\rest-http-error.ts:59:7)
              at validateValueAgainstSchema (D:\Workspace\javascript\opsdash-services-test\opsdash-services\packages\user-service\node_modules\@loopback\rest\src\validation\request-body.validator.ts:182:34)   
              at processTicksAndRejections (internal/process/task_queues.js:93:5)
              at Object.validateRequestBody (D:\Workspace\javascript\opsdash-services-test\opsdash-services\packages\user-service\node_modules\@loopback\rest\src\validation\request-body.validator.ts:75:3)     
              at buildOperationArguments (D:\Workspace\javascript\opsdash-services-test\opsdash-services\packages\user-service\node_modules\@loopback\rest\src\parser.ts:92:3)
      "code": "VALIDATION_FAILED",
      "details": [
        {
          "path": "/0/value",
          "code": "type",
          "message": "should be object",
          "info": {
            "type": "object"
          }
        },
        {
          "path": "/1/value",
          "code": "type",
          "message": "should be object",
          "info": {
            "type": "object"
          }
        },
        {
          "path": "/2/value",
          "code": "type",
          "message": "should be object",
          "info": {
            "type": "object"
          }
        }
      ],
      "status": 422,
      "statusCode": 422,
      "expose": true
    }
[2021-07-14T14:03:02.144Z] INFO (UserService/4892 on CHRDEV42725):
    requestId: "RequestContext-QuzkmMDRTbiTuMkFzvMHAA-19"
    correlationId: "QuzkmMDRTbiTuMkFzvMHAA-20"
    user: {
      "id": "00u14kjbo3IK5P8Fp5d7",
      "groups": []
    }
    req: {
      "method": "PATCH",
      "url": "/users/me",
      "query": {},
      "params": {},
      "headers": {
        "host": "localhost:8080",
        "connection": "keep-alive",
        "content-length": "171",
        "sec-ch-ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"",
        "authorization": "[Redacted]",
        "sec-ch-ua-mobile": "?0",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
        "content-type": "application/json-patch+json",
        "accept": "*/*",
        "origin": "http://localhost:3001",
        "sec-fetch-site": "same-site",
        "sec-fetch-mode": "cors",
        "sec-fetch-dest": "empty",
        "referer": "http://localhost:3001/",
        "accept-encoding": "gzip, deflate, br",
        "accept-language": "en-US,en;q=0.9",
        "x-correlation-id": "QuzkmMDRTbiTuMkFzvMHAA-20"
      },
      "remoteAddress": "::1",
      "remotePort": 63286
    }
    res: {
      "statusCode": 422,
      "headers": {
        "x-powered-by": "Express",
        "x-correlation-id": "QuzkmMDRTbiTuMkFzvMHAA-20",
        "access-control-allow-origin": "*",
        "access-control-allow-credentials": "true",
        "content-type": "application/problem+json; charset=utf-8",
        "content-length": "201",
        "etag": "W/\"c9-KXBlVP+3LvkN9OBVXa4YHIp4j2c\""
      }
    }
    duration: 156.0314
    event: "access"

Request body

[{"op":"add","path":"/learningStyle","value":"Intuitive"},{"op":"add","path":"/recognitionStyle","value":"Public"},{"op":"add","path":"/activityStyle","value":"Hands On"}]

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der @patch('/users/me')-Operation und ihrer @requestBody-Inhaltsdeklaration und reproduziere dann die Anfrage, während du anhand des Stack-Traces @loopback/rest/src/validation/request-body.validator.ts und parser.ts liest. Erledigt ist die Aufgabe, wenn die deklarierte application/json-patch+json-Anfrage konsistent verarbeitet wird und das gemeldete Verhalten der Request-Body-Validierung durch einen geeigneten Test abgedeckt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
nodejs, openapi, typescript
Bereich
api, backend
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.