README.md
1 # Custom API Routes 2 3 An API Route is a REST API endpoint. 4 5 An API Route is created in a TypeScript or JavaScript file under the `/src/api` directory of your Medusa application. The file’s name must be `route.ts` or `route.js`. 6 7 > Learn more about API Routes in [this documentation](https://docs.medusajs.com/learn/fundamentals/api-routes) 8 9 For example, to create a `GET` API Route at `/store/hello-world`, create the file `src/api/store/hello-world/route.ts` with the following content: 10 11 ```ts 12 import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"; 13 14 export async function GET(req: MedusaRequest, res: MedusaResponse) { 15 res.json({ 16 message: "Hello world!", 17 }); 18 } 19 ``` 20 21 ## Supported HTTP methods 22 23 The file based routing supports the following HTTP methods: 24 25 - GET 26 - POST 27 - PUT 28 - PATCH 29 - DELETE 30 - OPTIONS 31 - HEAD 32 33 You can define a handler for each of these methods by exporting a function with the name of the method in the paths `route.ts` file. 34 35 For example: 36 37 ```ts 38 import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"; 39 40 export async function GET(req: MedusaRequest, res: MedusaResponse) { 41 // Handle GET requests 42 } 43 44 export async function POST(req: MedusaRequest, res: MedusaResponse) { 45 // Handle POST requests 46 } 47 48 export async function PUT(req: MedusaRequest, res: MedusaResponse) { 49 // Handle PUT requests 50 } 51 ``` 52 53 ## Parameters 54 55 To create an API route that accepts a path parameter, create a directory within the route's path whose name is of the format `[param]`. 56 57 For example, if you want to define a route that takes a `productId` parameter, you can do so by creating a file called `/api/products/[productId]/route.ts`: 58 59 ```ts 60 import type { 61 MedusaRequest, 62 MedusaResponse, 63 } from "@medusajs/framework/http" 64 65 export async function GET(req: MedusaRequest, res: MedusaResponse) { 66 const { productId } = req.params; 67 68 res.json({ 69 message: `You're looking for product ${productId}` 70 }) 71 } 72 ``` 73 74 To create an API route that accepts multiple path parameters, create within the file's path multiple directories whose names are of the format `[param]`. 75 76 For example, if you want to define a route that takes both a `productId` and a `variantId` parameter, you can do so by creating a file called `/api/products/[productId]/variants/[variantId]/route.ts`. 77 78 ## Using the container 79 80 The Medusa container is available on `req.scope`. Use it to access modules' main services and other registered resources: 81 82 ```ts 83 import type { 84 MedusaRequest, 85 MedusaResponse, 86 } from "@medusajs/framework/http" 87 88 export const GET = async ( 89 req: MedusaRequest, 90 res: MedusaResponse 91 ) => { 92 const productModuleService = req.scope.resolve("product") 93 94 const [, count] = await productModuleService.listAndCount() 95 96 res.json({ 97 count, 98 }) 99 } 100 ``` 101 102 ## Middleware 103 104 You can apply middleware to your routes by creating a file called `/api/middlewares.ts`. This file must export a configuration object with what middleware you want to apply to which routes. 105 106 For example, if you want to apply a custom middleware function to the `/store/custom` route, you can do so by adding the following to your `/api/middlewares.ts` file: 107 108 ```ts 109 import { defineMiddlewares } from "@medusajs/framework/http" 110 import type { 111 MedusaRequest, 112 MedusaResponse, 113 MedusaNextFunction, 114 } from "@medusajs/framework/http"; 115 116 async function logger( 117 req: MedusaRequest, 118 res: MedusaResponse, 119 next: MedusaNextFunction 120 ) { 121 console.log("Request received"); 122 next(); 123 } 124 125 export default defineMiddlewares({ 126 routes: [ 127 { 128 matcher: "/store/custom", 129 middlewares: [logger], 130 }, 131 ], 132 }) 133 ``` 134 135 The `matcher` property can be either a string or a regular expression. The `middlewares` property accepts an array of middleware functions.