https:\/\/amzn.to\/3N19LvV<\/a><\/p>\n<\/blockquote>\n\n\n\nTo implement the repository pattern in JavaScript with Sequelize we first need to create an interface that describes it Sequelize model. Let’s go ahead and create TravelAttributes and TourAttributes interfaces.<\/p>\n\n\n\n
interface TravelAttributes {\n id: string;\n name: string;\n description: string;\n slug: string;\n is_public: boolean;\n number_of_days: number;\n tours: Array<TourAttributes>;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface TourAttributes {\n id: string;\n travel_id: string;\n name: string;\n starting_date: Date;\n ending_date: Date;\n price: number;\n created_at: Date;\n updated_at: Date;\n}<\/pre>\n\n\n\nNow we can pass those interfaces as generics to Travel and Tour models.<\/p>\n\n\n\n
@Table({\n timestamps: true,\n tableName: \"travels\",\n modelName: \"Travel\",\n})\nclass Travel extends Model<TravelAttributes> {\n @Column({\n primaryKey: true,\n type: DataType.UUID,\n defaultValue: DataType.UUIDV4,\n })\n declare id: string;\n...\n<\/pre>\n\n\n\n@Table({\n timestamps: true,\n tableName: \"tours\",\n modelName: \"Tour\",\n})\nclass Tour extends Model<TourAttributes> {\n @Column({\n primaryKey: true,\n type: DataType.UUID,\n defaultValue: DataType.UUIDV4,\n })\n declare id: string;\n...<\/pre>\n\n\n\nNow we can use TravelAttributes and TourAttributes as generics in Travel and Tour resources.<\/p>\n\n\n\n
import BaseResource from \".\/BaseResource\";\nimport TourResource from \".\/TourResource\";\n\nclass TravelResource extends BaseResource<TravelAttributes, TravelEntity>() {\n item() {\n const travelResource: TravelEntity = {\n id: this.instance.id,\n name: this.instance.name,\n description: this.instance.description || undefined,\n slug: this.instance.slug,\n number_of_days: this.instance.number_of_days,\n tours: TourResource.collection(this.instance.tours),\n };\n\n return travelResource;\n }\n}\n\nexport default TravelResource;\n<\/pre>\n\n\n\nimport BaseResource from \".\/BaseResource\";\n\nclass TourResource extends BaseResource<TourAttributes, TourEntity>() {\n item() {\n const tourResource: TourEntity = {\n id: this.instance.id,\n travel_id: this.instance.travel_id,\n name: this.instance.name,\n starting_date: this.instance.starting_date,\n ending_date: this.instance.ending_date,\n price: this.instance.price,\n };\n\n return tourResource;\n }\n}\n\nexport default TourResource;\n<\/pre>\n\n\n\nThe next step will be to create actual Travel and Tour repositories. We are going to use inheritance so Travel, Tour, and other repositories that come later will extend from Base repository class and re-use code as much as possible<\/p>\n\n\n\n
import { ModelStatic } from \"sequelize\";\n\nexport default abstract class BaseRepository<A> {\n modelClass: ModelStatic<any>;\n\n constructor(modelClass: ModelStatic<any>) {\n this.modelClass = modelClass;\n }\n\n getAll(options: Record<string, any> = {}): Promise<Array<A>> {\n if (!options.hasOwnProperty(\"order\")) {\n options = {\n ...options,\n ...this.getDefaultOrderBy(),\n };\n }\n\n return this.modelClass.findAll(options);\n }\n\n getById(id: string, options: Record<string, any> = {}): Promise<A> {\n return this.modelClass.findByPk(id, options);\n }\n\n protected getDefaultOrderBy() {\n return {\n order: [[\"created_at\", \"DESC\"]],\n };\n }\n}<\/pre>\n\n\n\nimport Tour from \"..\/database\/models\/Tour\";\nimport Travel from \"..\/database\/models\/Travel\";\nimport BaseRepository from \".\/BaseRepository\";\n\nexport default class TravelRepository extends BaseRepository<TravelAttributes> {\n constructor() {\n super(Travel);\n }\n\n getAll(options: Record<string, any> = {}) {\n const opts = {\n ...options,\n ...this.getIncludes(),\n };\n return super.getAll(opts);\n }\n\n getById(id: string, options: Record<string, any> = {}) {\n const opts = {\n ...options,\n ...this.getIncludes(),\n };\n return super.getById(id, opts);\n }\n\n private getIncludes() {\n return {\n include: Tour,\n };\n }\n}<\/pre>\n\n\n\nimport Tour from \"..\/database\/models\/Tour\";\nimport BaseRepository from \".\/BaseRepository\";\n\nexport default class TourRepository extends BaseRepository<TourAttributes> {\n constructor() {\n super(Tour);\n }\n}<\/pre>\n\n\n\nAs you can see, Travel repository has a more custom code, so it overwrites methods of the Base repository. However, Tour repository is quite simple and it uses methods of the parent class without implementing its own.<\/p>\n\n\n\n
Finally, lets use the repository inside travel and tour controllers instead of direct calls to Travel and Tour Sequelize models.<\/p>\n\n\n\n
const repository = new TravelRepository();\nconst travels = TravelResource.collection(await repository.getAll());\n\n...\n\nconst repository = new TravelRepository();\nconst travelResource = new TravelResource(await repository.getById(req.params.id));<\/pre>\n\n\n\nconst repository = new TourRepository();\nconst tours = TourResource.collection(await repository.getAll());\n\n...\n\nconst repository = new TourRepository();\nconst tourResource = new TourResource(await repository.getById(req.params.id));<\/pre>\n\n\n\nConlcusion<\/h2>\n\n\n\n We hope you now have a better understanding of the Repository Pattern and how to implement it in JavaScript to abstract calls made to the database. As you continue your journey as a JavaScript developer, keep the Repository Pattern in your toolkit. Whether you’re building a small-scale application or a large-scale enterprise system, this pattern can help you maintain clean, organized, and maintainable code.<\/p>\n","protected":false},"excerpt":{"rendered":"
The Repository Pattern is a structural pattern that abstracts and centralizes data access operations, providing a consistent and simplified interface for the application to interact with data sources. In essence, the Repository Pattern acts as a mediator or a middleman between the application’s business logic and the data storage, shielding the rest of the code…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[15],"tags":[17,18],"class_list":["post-30582","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-javascript","tag-patterns"],"yoast_head":"\n
Repository Pattern in JavaScript | Alex Rusin Blog<\/title>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n