For most server side work, [Actions](https://docs.gadget.dev/guides/actions) should be preferred over routes to offload your boilerplate code to Gadget. # HTTP routes ## What is an HTTP route in Gadget? An HTTP route is a server-side function that runs when a URL is visited to produce a response. Gadget matches incoming requests to routes based on each route's URL pattern, and then runs the handler function and sends the reply. Routes in Gadget are constructed using [Fastify routes](https://fastify.dev/docs/latest/Reference/Routes/), which means your handlers can use all of Fastify's capabilities including body parsing, validation, middleware support, and the Fastify plugin ecosystem. ## When do you use an HTTP route in Gadget? HTTP routes are used as an alternative solution to [Actions](https://docs.gadget.dev/guides/actions) when you need to specifically control the request input and output formats. Usually, Actions are the preferred way of working with your app, as you get an auto-generated, typesafe, performant API for each Action out of the box. HTTP routes work better when you need low-level control, like: * handling webhooks from connections not provided by Gadget (Ex. Stripe or Twilio) * dynamically generating files (Ex. PDFs or images) * serving static files For example, if you wanted to send an SMS every time a Shopify Product is created in a store, you would use a model action because Gadget has a connection that handles triggers for Shopify's webhooks. But, if you wanted to send an SMS when Stripe sends you a specific webhook, you'd listen to that webhook with an HTTP route and trigger your logic there. ## How an HTTP route works in Gadget HTTP routes in Gadget are defined as files in the `routes` folder. Each route has a specific filename which determines the URL path the route will be called at, like `GET-hello.js` or `/[slug]/POST-[id].js`. The route will be called whenever a request is made to a URL matching the pattern in the filename. HTTP routes run in your application's serverless runtime environment. Read more about the Gadget runtime environment in the [Runtime environment](https://docs.gadget.dev/guides/development-tools/runtime-environment) guide. Route files export a single function accepting a request context object. The request context includes: * a [`request`](https://www.fastify.dev/docs/latest/Reference/Request/) object for inspecting the incoming request headers, body, etc * a [`reply`](https://www.fastify.dev/docs/latest/Reference/Reply/) object for managing the response * a variety of other objects for working with your backend ## How to add an HTTP route to Shopify apps in Gadget Unlike the default web app template, when building a Shopify app (by choosing the Shopify template) it does not come with HTTP routes and its corresponding folder. To create an HTTP route in a Shopify app: 1. Press **CRTL** and click on the `API` folder and select **New folder**. 2. Name the folder `routes`. 3. Add a new JS file to the `routes` folder (for example we'll add `GET-data.js` as seen below). 4. In the newly created file you then should see the default code below: ```typescript import { RouteHandler } from "gadget-server"; /** * Route handler for GET data * * See: https://docs.gadget.dev/guides/http-routes/route-configuration#route-context */ const route: RouteHandler = async ({ request, reply, api, logger, connections, }) => {}; export default route; ``` Update the route so it returns a response: ```typescript import { RouteHandler } from "gadget-server"; const route: RouteHandler = async ({ reply }) => { await reply.send({ message: "Hello from your Gadget app route" }); }; export default route; ``` ### Calling the route You can now call this route at the `/data` path. For example: * `https://your-app-domain.gadget.app/data` in production * `https://your-app-domain--development.gadget.app/data` in development If you visit that URL in your browser, Gadget runs `api/routes/GET-data.ts` and returns the JSON response. If you are calling the route from a Gadget frontend, use `useFetch` or `api.fetch` so the request includes the right authentication headers. For example: ```tsx import { useFetch } from "@gadgetinc/react"; export default function Example() { const [{ data, fetching, error }, send] = useFetch("/data", { json: true }); return (
{JSON.stringify(data, null, 2)}}