MohamedBeydoun / atlas

An express-typescript code generator
Apache License 2.0
6 stars 0 forks source link

Database interactions functions require a resource id to be exposed #44

Open AsFal opened 4 years ago

AsFal commented 4 years ago

Problem

Ex:

This issue was found by executing the following command. atlas generate model another --fields name=string,friends=string[]

All comments will refer to code artifacts generated by the previous command.

Foreword

This issue implies an architecture choice that would force other changes on the current express service. Currently, the controllers layer is coupled with a MongoDb database, for the simple reason that you are exposing the Mongo Document interface when returning the "INew & Document" (aliased as "INewModel") type.

The following comments will adress an issue that arises if the Document interface is not exposed to the controllers layer.

Example

For the following command atlas generate model another --fields name=string,friends=string[]

Sample output

See the database/interactions/new.ts file.

    find: (newId: string): Promise<INew> => {
        return New.findOne({ _id: newId }).exec();
    },

See the interfaces/INew.ts

export interface INew { 
    friends: string;
    name: string;
}

The controller has no way of knowing a given database resource's id.

Proposal

Generated code for the interfaces/INew.ts

export interface INew {
    friends: string;
    name: string;
}

export type INewContent = Omit<INew, "_id">;
export type INewPartial = Partial<INew>;

Generated Code for the database/interactions/new.ts

export const newDBInteractions = {

    create: (neew: INewContent): Promise<INew> => {
        return New.create(neew);
    },

    all: (): Promise<INew[]> => {
        return New.find().exec();
    },

    find: (newId: string): Promise<INew> => {
        return New.findOne({ _id: newId }).exec();
    },

    update: (newId: string, newNew: INewPartial): Promise<INew> => {
        return New.findByIdAndUpdate(newId, newNew, { new: true }).exec();
    },

    delete: (newId: string): Promise<INew> => {
        return New.findByIdAndDelete(newId).exec();
    },
};
MohamedBeydoun commented 4 years ago

Why would we not expose INodeModel to the controllers?