EllC01
EllC01

Reputation: 1

Feathers.js (Express.js) service doesnt' work as REST

I'm setting up a little website using an Adaptable.io template to use on their service, but it uses frameworks i don't have knowledge (for ref, it's this package here https://adaptable.io/docs/starters/feathers-chat-starter). I managed to set up a couple of pages in react and a working "/images" service with sequelize . This service work alright with a websocket, but i would like to use it internally as a REST endpoint to perform insert operations without having to create an ad-hoc webpage. However, GET requests with postman on localhost:5050/images return html code event with Content-type: application/json, and the log doesn't show any query operation. I'll enclose app.js code for configuration, together with the service files:

//APP.JS
const { createServer } = require('http');
const path = require('path');
const favicon = require('serve-favicon');
const compress = require('compression');
const helmet = require('helmet');
const cors = require('cors');
const logger = require('./logger');

const feathers = require('@feathersjs/feathers');
const configuration = require('@feathersjs/configuration');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');


const middleware = require('./middleware');
const services = require('./services');
const session = require('./session');
const appHooks = require('./app.hooks');
const channels = require('./channels');

const authentication = require('./authentication');
const { connectAndSync, sequelize } = require('./sequelize');

const errorFilePath = path.join(__dirname, './error-page.html');

module.exports.createApp = function createApp() {
  const app = express(feathers());

  // Load app configuration
  app.configure(configuration());
  // Enable security, CORS, compression, favicon and body parsing
  app.use(helmet({
    contentSecurityPolicy: false
  }));
  app.use(cors());
  app.use(compress());
  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));
  app.use(favicon(path.join(app.get('public'), 'favicon.ico')));
  // Host the public folder
  app.use('/', express.static(app.get('public')));

  //redirect for client-side routing with react-router
  app.get('/*', function (req, res) {
     res.sendFile(path.join(app.get('public'), 'index.html'));
   });

  const tlsEnabled = app.get('tlsEnabled');
  if (typeof tlsEnabled !== 'boolean') throw new Error('Internal error: tlsEnabled not set');
  if (tlsEnabled) app.set('trust proxy', 1); // trust first proxy

  // Set up Plugins and providers
  app.configure(express.rest());
  app.configure(socketio());
  app.configure(sequelize);
  app.configure(session);

  // Configure other middleware (see `middleware/index.js`)
  app.configure(middleware);
  app.configure(authentication);
  // Set up our services (see `services/index.js`)
  app.configure(services);
  // Set up event channels (see channels.js)
  app.configure(channels);

  // Configure a middleware for the error handler
  //app.use(express.notFound());
  app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.sendFile(errorFilePath);
  });
  //middleware for error 404
  app.use(function (req, res, next) {
    res.status(404);
    res.sendFile(errorFilePath);
  });

  app.hooks(appHooks);
  return app;
};

module.exports.startApp = async function startApp(app) {
  const server = createServer(app);
  const port = app.get('port');

  app.setup(server);

  await connectAndSync(app);

  await new Promise((resolve, reject) => {
    let resolved = false;
    server.on('listening', () => {
      resolved = true;
      resolve();
    });
    server.on('error', (err) => {
      logger.error(`App server had an error: ${err.message}`, err);
      if (!resolved) {
        resolved = true;
        reject(err);
      }
    });
    server.listen(port);
  });
  return server;
};

//IMAGES.SERVICE.JS
// Initializes the `messages` service on path `/messages`
const { Images } = require('./images.class');
const createModel = require('../../models/images.model');
const hooks = require('./images.hooks');

module.exports = function (app) {
  const Model = createModel(app);
  const paginate = app.get('paginate');

  const options = {
    Model,
    paginate
  };

  // Initialize our service with any options it requires
  app.use('/images', new Images(options, app));

  // Get our initialized service so that we can register hooks
  const service = app.service('images');

  service.hooks(hooks);
};

//IMAGES.CLASS.JS
const { Service } = require('feathers-sequelize');

exports.Images = class Images extends Service {
  
};

//IMAGES.HOOKS.JS
const { authenticate } = require('@feathersjs/authentication').hooks;

const findAllImages = require('../../hooks/find-all-images');

module.exports = {
  before: {
    all: [],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  after: {
    all: [],
    find: [findAllImages()],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  error: {
    all: [],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  }
};

//FIND-ALL-IMAGES.JS HOOK
/* eslint-disable require-atomic-updates */
module.exports = function (options = {}) { // eslint-disable-line no-unused-vars
    return async context => {
        console.log("START find-all-images hook");
        // Get `app`, `method`, `params` and `result` from the hook context
        const { app, method, result, params } = context;
        // Function that adds the user to a single message object
        const findedImages = async (allImages) => {
            // Get the user based on their id, pass the `params` along so
            // that we get a safe version of the user data
            const imgQuery = await app.service('images').findAll();
            // Merge the message content to include the `user` object
            return {
                ...allImages,
                imgQuery
            };
        };

        // In a find method we need to process the entire page
        if (method === 'find') {
            // Map all data to include the `images` information
            context.result.data = await Promise.all(result.data.map(findedImages));
        } else {
            // Otherwise just update the single result
            context.result = await findedImages(result);
        }
        console.log("STOP find-all-images hook");
        return context;
    };
};

Tried to set a useragent service, create an ad-hoc service for rest api, modify app.js and webpack configuration

Upvotes: 0

Views: 26

Answers (0)

Related Questions