Browse Source

update api readme

Kasper 1 year ago
parent
commit
6579a134bf
1 changed files with 159 additions and 27 deletions
  1. 159 27
      src/api/README.md

+ 159 - 27
src/api/README.md

@@ -1,47 +1,179 @@
 # Custom endpoints
 # Custom endpoints
 
 
 You may define custom endpoints by putting files in the `/api` directory that export functions returning an express router or a collection of express routers.
 You may define custom endpoints by putting files in the `/api` directory that export functions returning an express router or a collection of express routers.
+Medusa supports adding custom endpoints using a file based approach. This means that you can add files in the `/api` directory and the files path will be used as the endpoint path. For example, if you add a file called `/api/store/custom/route.ts` it will be available on the `/store/custom` endpoint.
 
 
 ```ts
 ```ts
-import { Router } from "express"
-import { getConfigFile } from "medusa-core-utils"
-import { getStoreRouter } from "./routes/store"
-import { ConfigModule } from "@medusajs/medusa/dist/types/global";
+import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa";
 
 
-export default (rootDirectory) => {
-  const { configModule: { projectConfig } } = getConfigFile(
-    rootDirectory,
-    "medusa-config"
-  ) as { configModule: ConfigModule }
+export async function GET(req: MedusaRequest, res: MedusaResponse) {
+  res.json({
+    message: "Hello world!",
+  });
+}
+```
+
+## Supported HTTP methods
+
+The file based routing supports the following HTTP methods:
+
+- GET
+- POST
+- PUT
+- PATCH
+- DELETE
+- OPTIONS
+- HEAD
+
+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. For example, if you want to define a handler for the `GET`, `POST`, and `PUT` methods, you can do so by exporting functions with the names `GET`, `POST`, and `PUT`:
+
+```ts
+import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa";
 
 
-  const storeCorsOptions = {
-    origin: projectConfig.store_cors.split(","),
-    credentials: true,
-  }
+export async function GET(req: MedusaRequest, res: MedusaResponse) {
+  // Handle GET requests
+}
 
 
-  const storeRouter = getStoreRouter(storeCorsOptions)
+export async function POST(req: MedusaRequest, res: MedusaResponse) {
+  // Handle POST requests
+}
 
 
-  return [storeRouter]
+export async function PUT(req: MedusaRequest, res: MedusaResponse) {
+  // Handle PUT requests
 }
 }
 ```
 ```
 
 
+## Parameters
+
+You can define parameters in the path of your route by using wrapping the parameter name in square brackets. 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`:
+
+```ts
+import type {
+  MedusaRequest,
+  MedusaResponse,
+  ProductService,
+} from "@medusajs/medusa";
+
+export async function GET(req: MedusaRequest, res: MedusaResponse) {
+  const { productId } = req.params;
+
+  const productService: ProductService = req.scope.resolve("productService");
+
+  const product = await productService.retrieve(productId);
+
+  res.json({
+    product,
+  });
+}
+```
+
+If you want to define a route that takes multiple parameters, you can do so by adding multiple parameters in the path. It is important that each parameter is given a unique name. 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`. Duplicate parameter names are not allowed, and will result in an error.
+
+## Using the container
+
 A global container is available on `req.scope` to allow you to use any of the registered services from the core, installed plugins or your local project:
 A global container is available on `req.scope` to allow you to use any of the registered services from the core, installed plugins or your local project:
-```js
-import { Router } from "express"
 
 
-export default () => {
-  const router = Router()
+```ts
+import type {
+  MedusaRequest,
+  MedusaResponse,
+  ProductService,
+} from "@medusajs/medusa";
+
+export async function GET(req: MedusaRequest, res: MedusaResponse) {
+  const productService: ProductService = req.scope.resolve("productService");
 
 
-  router.get("/hello-product", async (req, res) => {
-    const productService = req.scope.resolve("productService")
+  const products = await productService.list();
+
+  res.json({
+    products,
+  });
+}
+```
 
 
-    const [product] = await productService.list({}, { take: 1 })
+## Middleware
 
 
-    res.json({
-      message: `Welcome to ${product.title}!`
-    })
-  })
+You can apply middleware to your routes by creating a file called `/api/middlewares.ts`. This file should export a configuration object with what middleware you want to apply to which routes. 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:
 
 
-  return router;
+```ts
+import type {
+  MiddlewaresConfig,
+  MedusaRequest,
+  MedusaResponse,
+  MedusaNextFunction,
+} from "@medusajs/medusa";
+
+async function logger(
+  req: MedusaRequest,
+  res: MedusaResponse,
+  next: MedusaNextFunction
+) {
+  console.log("Request received");
+  next();
 }
 }
+
+export const config: MiddlewaresConfig = {
+  routes: [
+    {
+      matcher: "/store/custom",
+      middlewares: [logger],
+    },
+  ],
+};
+```
+
+The `matcher` property can be either a string or a regular expression. The `middlewares` property accepts an array of middleware functions.
+
+You might only want to apply middleware to certain HTTP methods. You can do so by adding a `method` property to the route configuration object:
+
+```ts
+export const config: MiddlewaresConfig = {
+  routes: [
+    {
+      matcher: "/store/custom",
+      method: "GET",
+      middlewares: [logger],
+    },
+  ],
+};
+```
+
+The `method` property can be either a HTTP method or an array of HTTP methods. By default the middlewares will apply to all HTTP methods for the given `matcher`.
+
+### Default middleware
+
+Some middleware functions are applied per default:
+
+#### Global middleware
+
+JSON parsing is applied to all routes. This means that you can access the request body as `req.body` and it will be parsed as JSON, if the request has a `Content-Type` header of `application/json`.
+
+If you want to use a different parser for a specific route, such as `urlencoded`, you can do so by adding the following export to your `route.ts` file:
+
+```ts
+import { urlencoded } from "express";
+
+export const config: MiddlewaresConfig = {
+  routes: [
+    {
+      method: "POST",
+      matcher: "/store/custom",
+      middlewares: [urlencoded()],
+    },
+  ],
+};
+```
+
+#### Store middleware
+
+For all `/store` routes, the appropriate CORS settings are applied. The STORE_CORS value can be configured in your `medusa-config.js` file.
+
+#### Admin middleware
+
+For all `/admin` routes, the appropriate CORS settings are applied. The ADMIN_CORS value can be configured in your `medusa-config.js` file.
+
+All `/admin` routes also have admin authentication applied per default. If you want to disable this for a specific route, you can do so by adding the following export to your `route.ts` file:
+
+```ts
+export const AUTHENTICATE = false;
 ```
 ```