kurierjs / kurier

TypeScript framework to create JSON:API compliant APIs
https://kurier.readthedocs.io/en/latest/
MIT License
61 stars 9 forks source link

[1.3.x] Unable to use a custom type; it seems to be hard-coded (transformed) #363

Open nelson6e65 opened 11 months ago

nelson6e65 commented 11 months ago

I'm using version: kurier@1.3.0-beta10.

When I use GET /tenants, I get

{
  "errors": [
    {
      "status": 404,
      "code": "resource_not_found",
      "detail": "Resource tenant is not registered in the API Application"
    }
  ]
}

Type should be 'tenants', not 'tenant'. πŸ˜…

That's why it does not find the resource.

export class Tenant extends Resource {
  static schema = {
    attributes: {
      slug: String,
      name: String,
    },
    relationships: {},
  };

  static get type(): string {
    return 'tenants';
    // return this.getCollectionName();
  }

  static getCollectionName(): string {
    const className: string = this.name;

    return underscore(camelize(pluralize(className)));
  }
}

On this line of convertHttpRequestToOperation function, it is hard-coding the type, converting it to singular camel-case version: https://github.com/kurierjs/kurier/blob/9874656ead05e645e699fe518f96a6de1c2815ab/src/utils/http-utils.ts#L78C48-L78C48

const type = camelize(singularize(resource));
joelalejandro commented 11 months ago

Hey @nelson6e65! Thank you for reporting this. Type names are expected to be singularized for the router to work.

Can you share your app.ts file? In particular, the app instantiation. This might be a problem related to how the resource is being registered.

nelson6e65 commented 11 months ago

@joelalejandro Sure! Here you are!

// server.ts
import express from 'express';
import { jsonApiExpress, Application } from 'kurier';

import { FirebaseProcessor } from '~api/v1/processors/firebase.processor';
import { Tenant } from '~api/v1/resources/tenant';
import { User } from '~api/v1/resources/user';
import { JsonApiApplication } from '~utils/json-api/json-api-application';

const app = new Application({
  types: [
    //
    User,
    Tenant,
  ],
  defaultProcessor: FirebaseProcessor,
});

const server = express();

server.use(
  jsonApiExpress(app, {
    httpStrictMode: true,
  })
);

export default server;

My FirebaseProcessor it just extends OperationProcessor, I have not done anything yet.

```ts /* eslint-disable @typescript-eslint/require-await */ import { HasId, Operation, OperationProcessor, Resource } from 'kurier'; /** * Preprocessor for firebase. */ export class FirebaseProcessor extends OperationProcessor { async get(op: Operation): Promise { if (op.ref.id) { return await this.getOne(op); } return this.getMany(op); } protected async getMany(op: Operation): Promise { return [ { // ...just testing data }, { // ... }, ]; } protected async getOne(op: Operation): Promise { const data: HasId = { id: op.ref.id, // ... }; return data; } async remove(op: Operation): Promise { throw new Error('Method not implemented.'); } async update(op: Operation): Promise { throw new Error('Method not implemented.'); } async add(op: Operation): Promise { throw new Error('Method not implemented.'); } } ```