Search code examples
proxyfetchshopifyshopify-appshopify-api

How do I set the app proxy URL for a Shopify app?


I understand that I need to set up an app proxy to make requests to my Postgres DB and for the app-extensions. However, I keep getting 404 errors for a bad URI - I'm not understanding how to do this properly.

All I want to do is post to Postgres (on Heroku) by making a frontend call to my API. The app-proxy config is attached below.

I'm trying to make an authenticaed call via useFetch() hook: merchant.tsx

const BASE_URL = "/apps/my-app-proxy";
const postBody = {
  id: 1,
  name: "Test",
  account: "0x.....",
  campaign_id: 1,
};

useFetch(`${BASE_URL}/api/merchant/`, {
        headers: {
          "Content-Type": "application.json",
          "Access-Control-Allow-Origin": "*",
        },
        body: JSON.stringify(postBody),
        method: "POST",
      }).then((res) => {
        console.log("POST merchant: ", res);
      });

The response returns as: 404: JSON Response The App proxy config I am using: App Proxy config

The endpoints in merchant.ts are NOT being hit. How do I actually call the proxy url to call my endpoints?

index.ts:

    // add new routes with router in here
    app.use("/api/merchant", merchantRouter);

merchant.ts:

import express from "express";
import { Merchant } from "../models/Models";
const router = express.Router();
// NOTE: These routes deal with all merchant requests

// TODO: connect database to shopify
// Authentication to prevent aanyone from calling
// or already done by shopify?
router.post("/", async (req, res) => {
    try {
        // TODO: check if merchant already exsits (shopify acc/email?)
        console.log('MERCHANT ENDPOINT')
        const merchant = req.body;
        await Merchant.create(merchant);
        res.json(merchant);
    } catch (e) {
        console.error('ERROR: ', e);
    }
})

router.get("/", async (req, res) => {
  try {
    console.log('GET MERCHANTS called ', req)
    const merchants = await Merchant.findAll();
    res.json(merchants);
  } catch (e) {
    console.error("ERROR: ", e);
  }
});

router.get("/:id", async (req, res) => {
  try {
    const id = req.params.id;
    const merchant = await Merchant.findByPk(id);
    res.json(merchant);
  } catch (e) {
    console.error("Error: ", e);
  }
});

export default router;


Solution

  • First off. In Shopify, App setup, Proxy. You decide your internal App endpoint. That will be your ngrok address plus whatever accepts a GET or POST from Shopify. You also get to tell Shopify what URL you want the front-end store to use. That is your choice of /a/foo or /tools/hammer or /community/beers or whatever.

    Note that with these things set in Shopify, the merchant can still tinker in their Admin, and change your nice /a/foo to /a/poo and you'd never know.

    In your front-end code, in the store theme, you want to access your proxy, so you write some JS to do a GET or POST to match what your App expects, sending the request to /a/foo or whatever you set in your App.

    It really is both that easy and that frustratingly hard. Why oh why! App Proxy, forever in my heart. Forever hard to deal with.