--- slug: /references/file-provider-module --- import { TypeList } from "docs-ui" # How to Create a File Provider Module In this document, you’ll learn how to create a file provider module and the methods you must implement in its main service. --- ## 1. Create Module Directory Start by creating a new directory for your module. For example, `src/modules/my-file`. --- ## 2. Create the File Provider Service Create the file `src/modules/my-file/service.ts` that holds the implementation of the module's main service. It must extend the `AbstractFileProviderService` class imported from `@medusajs/framework/utils`: ```ts title="src/modules/my-file/service.ts" import { AbstractFileProviderService } from "@medusajs/framework/utils" class MyFileProviderService extends AbstractFileProviderService { // TODO implement methods } export default MyFileProviderService ``` ### constructor The constructor allows you to access resources from the module's container using the first parameter, and the module's options using the second parameter. If you're creating a client or establishing a connection with a third-party service, do it in the constructor. #### Example ```ts import { Logger } from "@medusajs/framework/types" import { AbstractFileProviderService } from "@medusajs/framework/utils" type InjectedDependencies = { logger: Logger } type Options = { apiKey: string } class MyFileProviderService extends AbstractFileProviderService { protected logger_: Logger protected options_: Options static identifier = "my-file" // assuming you're initializing a client protected client constructor ( { logger }: InjectedDependencies, options: Options ) { super() this.logger_ = logger this.options_ = options // assuming you're initializing a client this.client = new Client(options) } } export default MyFileProviderService ``` ### constructor ### validateOptions This method validates the options of the provider set in `medusa-config.ts`. Implementing this method is optional. It's useful if your provider requires custom validation. If the options aren't valid, throw an error. #### Example ```ts class MyFileProviderService extends AbstractFileProviderService { static validateOptions(options: Record) { if (!options.apiKey) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "API key is required in the provider's options." ) } } } ``` #### Parameters `","description":"The provider's options.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="validateOptions"/> #### Returns ### upload This method uploads a file using your provider's custom logic. #### Example ```ts class MyFileProviderService extends AbstractFileProviderService { // ... async upload( file: ProviderUploadFileDTO ): Promise { // TODO upload file to third-party provider // or using custom logic return { url: "some-url.com", key: "file-name" } } } ``` #### Parameters #### Returns ### delete This method deletes the file from storage. #### Example ```ts class MyFileProviderService extends AbstractFileProviderService { // ... async delete(file: ProviderDeleteFileDTO): Promise { // TODO logic to remove the file from storage // Use the `file.fileKey` to delete the file // for example: this.client.delete(file.fileKey) } } ``` #### Parameters #### Returns ### getPresignedDownloadUrl This method is used to retrieve a download URL of the file. For some providers, such as S3, a presigned URL indicates a temporary URL to get access to a file. If your provider doesn’t perform or offer a similar functionality, you can return the URL to download the file. #### Example ```ts class MyFileProviderService extends AbstractFileProviderService { // ... async getPresignedDownloadUrl( fileData: ProviderGetFileDTO ): Promise { // TODO logic to get the presigned URL // Use the `file.fileKey` to delete the file // for example: return this.client.getPresignedUrl(fileData.fileKey) } } ``` #### Parameters #### Returns --- ## 3. Create Module Definition File Create the file `src/modules/my-file/index.ts` with the following content: ```ts title="src/modules/my-file/index.ts" import MyFileProviderService from "./service" import { ModuleProvider, Modules } from "@medusajs/framework/utils" export default ModuleProvider(Modules.FILE, { services: [MyFileProviderService], }) ``` This exports the module's definition, indicating that the `MyFileProviderService` is the module's service. --- ## 4. Use Module To use your File Module Provider, add it to the `providers` array of the File Module in `medusa-config.ts`: The File Module accepts one provider only. ```ts title="medusa-config.ts" import { Modules } from "@medusajs/framework/utils" // ... module.exports = defineConfig({ // ... modules: [ { resolve: "@medusajs/medusa/file", options: { providers: [ { resolve: "./src/modules/my-file", id: "my-file", options: { // provider options... }, }, ], }, }, ] }) ``` --- ## 5. Test it Out To test out your file provider, use the Medusa Admin or the [Upload API route](https://docs.medusajs.com/v2/api/admin#uploads_postuploads) to upload a file.