* added integration * add segment for API reference * updated frontend checkout flow * added paypal documentation * Improve storefront quickstart documents * added documentation for entities * docs: disable running tests for docs * added docs contribution guidelines * Use npm2yarn where missing * added additional steps section * added notification overview * Added guidelines for sidebar labels * added how to create notification provider * fixes * fixes for payment provider * fixes * chore(deps): bump sqlite3 from 5.0.2 to 5.0.3 (#1453) Bumps [sqlite3](https://github.com/TryGhost/node-sqlite3) from 5.0.2 to 5.0.3. - [Release notes](https://github.com/TryGhost/node-sqlite3/releases) - [Changelog](https://github.com/TryGhost/node-sqlite3/blob/master/CHANGELOG.md) - [Commits](https://github.com/TryGhost/node-sqlite3/compare/v5.0.2...v5.0.3) * fix: Issue with cache in CI pipeline * Use npm2yarn where missing * added integration * add segment for API reference * fix double segment * updated frontend checkout flow * added documentation for entities * added docs contribution guidelines * Added guidelines for sidebar labels * added additional steps section * added notification overview * added how to create notification provider * chore: Add issue template for bug reports (#1676) * chore: Add issue template for feature requests (#1679) * fixes * fixes for payment provider * fixes Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
5.9 KiB
Create Endpoint for Storefront
In this document, you’ll learn how to add a custom endpoint in the Backend that you can use from the Storefront.
Overview
Custom endpoints reside under the src/api directory in your Medusa Backend. To define a new endpoint, you can add the file index.js under the src/api directory. This file should export a function that returns an Express router.
Your endpoint can be under any path you wish. By Medusa’s conventions, all Storefront REST APIs are prefixed by /store. For example, the /store/products lets you retrieve the products to display them on your storefront.
Implementation
To create a new endpoint, start by creating a new file in src/api called index.js. At its basic format, index.js should look something like this:
import { Router } from "express"
export default () => {
const router = Router()
router.get("/store/hello", (req, res) => {
res.json({
message: "Welcome to My Store!",
})
})
return router
}
This exports a function that returns an Express router. In that function, you can create one or more endpoints. In the example above, you create the endpoint /store/hello.
Now, if you run your server and send a request to /store/hello, you will receive a JSON response message.
:::note
Custom endpoints are compiled into the dist directory of your Backend when you run your server using medusa develop, while it’s running, and when you run:
npm run build
:::
Accessing Endpoints from Storefront
If you’re customizing one of our storefronts or creating your own, you need to use the cors library.
First, you need to import your Medusa’s configurations along with the cors library:
import cors from "cors"
import { projectConfig } from "../../medusa-config"
Then, create an object that will hold the CORS configurations:
const corsOptions = {
origin: projectConfig.store_cors.split(","),
credentials: true,
}
Finally, for each route add cors as a middleware for the route passing it corsOptions:
router.get("/store/hello", cors(corsOptions), (req, res) => {
//...
})
Multiple Endpoints
Same File
You can add more than one endpoints in src/api/index.js:
router.get("/store/hello", (req, res) => {
res.json({
message: "Welcome to My Store!",
})
})
router.get("/store/bye", (req, res) => {
res.json({
message: "Come back again!",
})
})
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 src/api/hello.js with the following content:
export default (router) => {
router.get("/store/hello", (req, res) => {
res.json({
message: "Welcome to My Store!",
})
})
}
You export a function that receives an Express router as a parameter and adds the endpoint store/hello to it.
Next, create the file src/api/bye.js with the following content:
export default (router) => {
router.get("/store/bye", (req, res) => {
res.json({
message: "Come back again!",
})
})
}
Again, you export a function that receives an Express router as a parameter and adds the endpoint store/bye to it.
Finally, in src/api/index.js import the two functions at the beginning of the file:
import helloRoute from "./hello"
import byeRoute from "./bye"
and in the exported function, call each of the functions passing them the Express router:
export default () => {
const router = Router()
helloRoute(router)
byeRoute(router)
return router
}
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 ProductService to retrieve products or perform operations like creating or updating a product.
You can retrieve any registered service in your endpoint using req.scope.resolve passing it the service’s registration name.
Here’s an example of an endpoint that retrieves the count of products in your store:
router.get("/store/products/count", (req, res) => {
const productService = req.scope.resolve("productService")
productService.count().then((count) => {
res.json({
count,
})
})
})
The productService has a count method that returns a Promise. This Promise resolves to the count of the products. You return a JSON of the product count.
Protected Routes
Protected routes are routes that should be accessible by logged-in customers only.
To make a route protected, first, import the authenticate middleware:
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate"
Then, add the middleware to your route:
router.get("/store/products/count", authenticate(), (req, res) => {
//...
})
Now, only authenticated users can access this endpoint.
Accessing Current Customer
You can get the logged-in customer’s ID using req.user:
const id = req.user.customer_id
To get the customer’s details, you can use the customerService:
const id = req.user.customer_id
const customerService = req.scope.resolve("customerService")
const customer = await customerService.retrieve(id)
Route Parameters
The routes you create receive 2 parameters. The first one is the absolute path to the root directory that your server is running from. The second one 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.
export default (rootDirectory, pluginOptions) => {
const router = Router()
//...
}