Skip to main content

How to Create Endpoints

In this document, you’ll learn how to create endpoints in your Medusa server.

Overview

Custom endpoints reside under the Copy to Clipboard directory in your Medusa Backend. They're defined in a TypeScript or JavaScript file that is named Copy to Clipboard (for example, Copy to Clipboard). This file should export a function that returns an Express router.

Implementation

To create a new endpoint, start by creating a new file in Copy to Clipboard called Copy to Clipboard. At its basic format, Copy to Clipboard should look something like this:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import { Router } from "express"

export default (rootDirectory, pluginOptions) => {
const router = Router()

router.get("/hello", (req, res) => {
res.json({
message: "Welcome to My Store!",
})
})

return router
}
Copy to Clipboard

This exports a function that returns an Express router. The function receives two parameters:

  • Copy to Clipboard is the absolute path to the root directory that your server is running from.
  • Copy to Clipboard is an object that has your plugin's options. If your API route is not implemented in a plugin, then it will be an empty object.

Endpoints Path

Your endpoint can be under any path you wish.

By Medusa’s conventions:

  • All Storefront REST APIs are prefixed by Copy to Clipboard. For example, the Copy to Clipboard endpoint lets you retrieve the products to display them on your storefront.
  • All Admin REST APIs are prefixed by Copy to Clipboard. For example, the Copy to Clipboard endpoint lets you retrieve the products to display them on your Admin.

You can also create endpoints that don't reside under these two prefixes, similar to the Copy to Clipboard endpoint in the previous example.

CORS Configuration

If you’re adding a storefront or admin endpoint and you want to access these endpoints from the storefront or Medusa admin, you need to pass your endpoints Cross-Origin Resource Origin (CORS) options using the Copy to Clipboard package.

First, you need to import your Medusa configurations along with the Copy to Clipboard library:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import cors from "cors"
import { projectConfig } from "../../medusa-config"
Copy to Clipboard

Then, create an object that will hold the Cross-Origin Resource Sharing (CORS) configurations. If it’s a storefront endpoint, pass the Copy to Clipboard property storefront options:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
const corsOptions = {
origin: projectConfig.store_cors.split(","),
credentials: true,
}
Copy to Clipboard

If it’s an admin endpoint, pass the Copy to Clipboard property admin options:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
const corsOptions = {
origin: projectConfig.admin_cors.split(","),
credentials: true,
}
Copy to Clipboard

Finally, for each route you add, create an Copy to Clipboard request and add Copy to Clipboard as a middleware for the route:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
router.options("/admin/hello", cors(corsOptions))
router.get("/admin/hello", cors(corsOptions), (req, res) => {
//...
})
Copy to Clipboard

Create Multiple Endpoints

Same File

You can add more than one endpoint in Copy to Clipboard:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
router.options("/store/hello", cors(storeCorsOptions))
router.get("/store/hello", cors(storeCorsOptions), (req, res) => {
res.json({
message: "Welcome to Your Store!",
})
})

router.options("/admin/hello", cors(adminCorsOptions))
router.get("/admin/hello", cors(adminCorsOptions), (req, res) => {
res.json({
message: "Welcome to Your Admin!",
})
})
Copy to Clipboard

Multiple Files

Alternatively, you can add multiple files for each endpoint or set of endpoints for readability and easy maintenance.

To do that with the previous example, first, create the file Copy to Clipboard with the following content:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import cors from "cors"
import { projectConfig } from "../../medusa-config"

export default (router) => {
const storeCorsOptions = {
origin: projectConfig.store_cors.split(","),
credentials: true,
}
router.options("/store/hello", cors(storeCorsOptions))
router.get("/store/hello", cors(storeCorsOptions), (req, res) => {
res.json({
message: "Welcome to Your Store!",
})
})
}
Copy to Clipboard

You export a function that receives an Express router as a parameter and adds the endpoint Copy to Clipboard to it.

Next, create the file Copy to Clipboard with the following content:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import cors from "cors"
import { projectConfig } from "../../medusa-config"

export default (router) => {
const adminCorsOptions = {
origin: projectConfig.admin_cors.split(","),
credentials: true,
}
router.options("/admin/hello", cors(adminCorsOptions))
router.get("/admin/hello", cors(adminCorsOptions), (req, res) => {
res.json({
message: "Welcome to Your Admin!",
})
})
}
Copy to Clipboard

Again, you export a function that receives an Express router as a parameter and adds the endpoint Copy to Clipboard to it.

Finally, in Copy to Clipboard import the two functions at the beginning of the file:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import storeRoutes from "./store"
import adminRoutes from "./admin"
Copy to Clipboard

and in the exported function, call each of the functions passing them the Express router:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
export default () => {
const router = Router()

storeRoutes(router)
adminRoutes(router)

return router
}
Copy to Clipboard

Protected Routes

Protected routes are routes that should be accessible by logged-in customers or users only.

Protect Store Routes

To make a storefront route protected, first, import the Copy to Clipboard middleware:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate-customer"
Copy to Clipboard

Then, add the middleware to your route:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
router.options("/store/hello", cors(corsOptions))
router.get("/store/hello", cors(corsOptions), authenticate(), async (req, res) => {
if (req.user) {
//user is logged in
//to get customer id: req.user.customer_id
}
//...
})
Copy to Clipboard

Please note that the endpoint is still accessible by all users, however, you’ll be able to access the current logged-in customer if there’s any.

To disallow guest customers from accessing the endpoint, you can throw an error if Copy to Clipboard is Copy to Clipboard.

Protect Admin Routes

To make an admin route protected, first, import the Copy to Clipboard middleware:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate"
Copy to Clipboard

Then, add the middleware to your route:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
router.options("/admin/products/count", cors(corsOptions))
router.get("/admin/products/count", cors(corsOptions), authenticate(), async (req, res) => {
//access current user
const id = req.user.userId
const userService = req.scope.resolve("userService")

const user = await userService.retrieve(id)
//...
})
Copy to Clipboard

Now, only authenticated users can access this endpoint.

Use Services

Services in Medusa bundle a set of functionalities into one class. Then, you can use that class anywhere in your backend. For example, you can use the Copy to Clipboard to retrieve products or perform operations like creating or updating a product.

You can retrieve any registered service in your endpoint using Copy to Clipboard passing it the service’s registration name.

Here’s an example of an endpoint that retrieves the count of products in your store:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
router.get("/admin/products/count", cors(corsOptions), authenticate(), (req, res) => {
const productService = req.scope.resolve("productService")

productService.count().then((count) => {
res.json({
count,
})
})
})
Copy to Clipboard

The Copy to Clipboard has a Copy to Clipboard method that returns a Promise. This Promise resolves to the count of the products. You return a JSON of the product count.

Building Files

Custom endpoints must be transpiled and moved to the Copy to Clipboard directory. This happens when you run your server using Copy to Clipboard and while it’s running, and when you run the following command:

Report Incorrect CodeReport Incorrect CodeReport Incorrect CodeCopy to Clipboard
npm run build
Copy to Clipboard

What’s Next