nikhil mehta
nikhil mehta

Reputation: 1032

Nodejs Express Router REST APIs using azure app service

I have an app service in my azure account, Which is running a node application (Express, Angular and websockets). I am able to serve static contents to my users but the REST APIs are failing with 404 not found error.

Following is my code in my index.js

var os = require('os');
var fs = require("fs");
var bodyParser = require('body-parser');
var express = require('express'),
    expressApp = express(),
    socketio = require('socket.io'),
    http = require('http'),
    uuid = require('node-uuid'),
    config = require('../config/config.json');

var httpServer = http.createServer(expressApp),
    rooms = {},
    userIds = {};
expressApp.use(express.static(__dirname + '/../public/dist/'));
expressApp.use(bodyParser.urlencoded({ extended: true }));
expressApp.use(bodyParser.json());
var router = express.Router();
expressApp.use('/api', router);
router.get('/getsomethings', function(req, res) {
    res.json(something);
});
expressApp.use('/api', router);
expressApp.listen = function listen() {
    httpServer.listen(config.PORT);
};

expressApp.listen();
exports.run = function(config) {

    //some code
};

And following is my web.config for app.service

<configuration>
  <system.webServer>

    <handlers>
      <!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
      <add name="iisnode" path="index.js" verb="*" modules="iisnode" />
    </handlers>

    <rewrite>
      <rules>        
        <!-- Don't interfere with requests for node-inspector debugging -->
        <clear />
        <rule name="Redirect to https" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTPS}" pattern="off" ignoreCase="true" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
        </rule>

        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="^index.js\/debug[\/]?" />
        </rule>

        <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}" />
        </rule>
        <!-- All other URLs are mapped to the Node.js application entry point -->
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
          </conditions>
          <action type="Rewrite" url="index.js" />
        </rule>
      </rules>
    </rewrite>
    <security>
       <requestFiltering>
         <hiddenSegments>
           <add segment="node_modules" />
         </hiddenSegments>
       </requestFiltering>
     </security>
    <!-- You can control how Node is hosted within IIS using the following options -->
    <!--<iisnode      
          node_env="%node_env%"
          nodeProcessCountPerApplication="1"
          maxConcurrentRequestsPerProcess="1024"
          maxNamedPipeConnectionRetry="3"
          namedPipeConnectionRetryDelay="2000"      
          maxNamedPipeConnectionPoolSize="512"
          maxNamedPipePooledConnectionAge="30000"
          asyncCompletionThreadCount="0"
          initialRequestBufferSize="4096"
          maxRequestBufferSize="65536"
          watchedFiles="*.js"
          uncFileChangesPollingInterval="5000"      
          gracefulShutdownTimeout="60000"
          loggingEnabled="true"
          logDirectoryNameSuffix="logs"
          debuggingEnabled="true"
          debuggerPortRange="5058-6058"
          debuggerPathSegment="debug"
          maxLogFileSizeInKB="128"
          appendToExistingLog="false"
          logFileFlushInterval="5000"
          devErrorsEnabled="true"
          flushResponse="false"      
          enableXFF="false"
          promoteServerVars=""
         />-->

  </system.webServer>
</configuration>

When I access my site Everything is working fine except that /getsomethings XHR is giving 404 error. All static contents are served fine.

Can anyone help me to figure out what is wrong?

Upvotes: 1

Views: 766

Answers (1)

Aaron Chen
Aaron Chen

Reputation: 9950

You say "I am able to serve static contents to my users", because you have this in web.config.

<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
    <action type="Rewrite" url="public{REQUEST_URI}" />
</rule>

Based on the code you provided above, please make sure your folder structure looks like:

D:\home\site
├── config  
│   └── config.json
├── deployments 
│   └── ...
├── locks
│   └── ...
├── Diagnostics
│   └── ...
├── public
│   └── dist
│       └── ...
└── wwwroot
    ├── node_modules 
    │   └── ...
    ├── index.js
    ├── package.json
    └── web.config

Also, Please try changing the following line of code:

httpServer.listen(config.PORT);

to:

httpServer.listen(process.env.PORT || config.PORT);

Upvotes: 1

Related Questions