8

I want to create an API that can be called by the app itself (whether "ajax" or server-rendered) and other clients (e.g. mobile app). Most of the articles I found when googling "Quasar REST API" talk about how to access external APIs, which is not my case.

My understanding is to modify src-ssr/extension.js:

module.exports.extendApp = function({app, ssr}) {
  app.get('/api/bla', (req, res) => {
    res.send('something')
  })
}

and ensure port inside src-ssr/index.js:

const ssr = require('../ssr'),
      extension = require('./extension'),
      app = express(),
      port = process.env.PORT || 8888

matches the value in quasar.conf.js:

devServer: {
  https: false,
  open: false,
  port: 8888,
},

The project builds and runs successfully, but http://localhost:8888/api/bla keeps loading in the browser. What do I miss?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
wiradikusuma
  • 1,930
  • 4
  • 28
  • 44

1 Answers1

0

Please see my answer here.


  • src-ssr/middlewares/api.ts custom middleware to catch hits on /api/* and when a configured route is found, the api handler will be loaded and executed
import { ssrMiddleware } from 'quasar/wrappers'
import routes from '../../src/api/_routes'
import type { Request, Response } from 'express'
import { parse } from 'url'

export default ssrMiddleware(async ({ app, resolve }) => {
    app.all(resolve.urlPath('*'), async (req: Request, res: Response, next) => {
        const { pathname } = parse(req.url)
        if (!pathname || !pathname.startsWith('/api')) {
            return next()
        }

        const path = pathname.replace(/^\/api/, '')

        if (!Object.keys(routes).includes(path)) {
            res.sendStatus(404).end()
            return
        }

        console.log(`API hit on ${path}`)

        try {
            const handler = (await routes[path as keyof typeof routes]())
                .default
            handler(req, res)
        } catch (error) {
            console.error(error)
            res.sendStatus(500).end()
        }
    })
})

  • You configure your api routes in src/api/routes.ts like:
const routes = {
    '/ping': () => import('./ping'),
}

export default routes
  • And write your api routes along, e.g. src/api/ping.ts
import type { Request, Response } from 'express'

export default function (req: Request, res: Response) {
    res.status(200).send('pong')
}
David Wolf
  • 1,400
  • 1
  • 9
  • 18