title: What is the proper method on Heroku to proxy Angular calls to a back-end API?
body: <p>Note:  Updated 2019 JUN 04; see below</p>
  
  <p>This is not a question about a particular snippet of code; rather, I am seeking help properly architecting the proxy for an Angular client communicating with a back-end API using the MEAN stack (MongoDB, Express, Angular, Node).  I’m an old school C programmer who is self-teaching himself MEAN.  Old dog, new trick.  I’ve scrubbed several resources, including Stack Overflow, but I haven’t found the answer.  Several users on Stack Overflow are reporting the same problem (I’ve listed those under SOURCES).  I also have a help ticket with Heroku.</p>
  
  <p>Thank you to everyone who reads this and considers it.  An extra thanks (in advance) to all those who post helpful suggestions and solutions.</p>
  
  <p>QUESTION:  How do you correctly architect an Angular client’s calls to a back-end API to avoid the problems inherent in CORS (Cross-Origin Resource Sharing)?  The solution I drew and developed from Angular documentation, proxies, works when running on my development system (i.e. localhost), but it fails when uploaded to my PaaS (Heroku).  Is this because Angular’s proxies are a tool only for development?  If so, what is the proper method for calling a back-end API?</p>
  
  <p>CONFIGURATION:  I’m developing on Darwin OS (macOS 10.14.4), using Node 10.13.0, npm 6.9.0, Express 4.16.2, and Angular 7.2.9.  I’m using a git repository on Bitbucket which pipelines deployments to Heroku.  I have separate deployments for the client (Angular) and the API (Node/Express).  Right now the client is running on a Hobby dyno and the API on a Free dyno on Heroku.  My database is hosted on mLab in a Sandbox (free database).
  Client:  <a href="https://www.markwilx.com" rel="nofollow noreferrer">https://www.markwilx.com</a>
  API:  <a href="http://markwilx-api.herokuapp.com/api/test" rel="nofollow noreferrer">http://markwilx-api.herokuapp.com/api/test</a></p>
  
  <p>DISCUSSION:  The following question in Stack Overflow is the same problem I’m experiencing:
  <a href="https://stackoverflow.com/questions/53327160/angular-proxy-conf-json-to-call-api-works-locally-but-not-on-heroku">Angular proxy.conf.json to call API works locally but not on Heroku</a>
  There is no solution given but Massimiliano Sartoretto makes a comment that states:
  “That proxy is supposed to work only for the development server. It has nothing to do with Heroku and it's shouldn't even be deployed on Heroku. Its goal is to help you proxy external API calls while serving the app from localhost”
  I have a problem with this comment. The official Angular documentation (see SOURCES, below) makes no mention of this.  I’m not challenging Mr. Sartoretto’s claim, but I certainly assert that his claim is not widely known nor documented.  If anyone is aware of this fact, I’d appreciate a reference where I can read about it.</p>
  
  <p>Likewise, Mr. Chenkie, who uses the same method, does not mention this in his book (see SOURCES, below).  I have tried several times over several months to ask Mr. Chenkie, via his website, but he has not responded.  When/if he does, I will update this post.</p>
  
  <p>The good team at Heroku have responded to my help ticket.  Heroku does not provide the native proxying capability, so any proxy must be handled in the Angular client.  They are inclined to believe the problem lies somewhere within Mr. Sartoretto’s claim.  Describing how I should architect my client and API is, of course, outside the scope of their service.</p>
  
  <p>Finally, I found the following on Stack Overflow
  <a href="https://stackoverflow.com/questions/12096528/proxy-server-with-node-js-on-heroku">Proxy server with Node.js on Heroku</a>
  This, again, is the same problem I’m having.    The person asking the question, Andrea Reginato, is not using Angular, but he posted his work-around for Node.  I’m wondering if this is the preferred method and I just need to port it into Angular.</p>
  
  <p>I’m really stuck and I want to make sure I build my system with the industry best-practice techniques.</p>
  
  <p>SOURCES:  The official Angular documentation on configuring a proxy to a back-end server is given at this link:
  <a href="https://angular.io/guide/build#proxying-to-a-backend-server" rel="nofollow noreferrer">https://angular.io/guide/build#proxying-to-a-backend-server</a></p>
  
  <p>I’ve been reading and following “Securing Angular Applications” by Ryan Chenkie.  Beginning on pages 41, he begins the process of demonstrating how to build a proxy for his examplar application.  His example is consistent with the methods in the above Angular documentation.</p>
  
  <p>Here are unsolved queries on Stack Overflow that are strongly related to the problem I am having:</p>
  
  <p>[I had to remove all of them.  With them included, Stack Overflow decided my post was spam.  I put the most important ones in the text above.]</p>
  
  <hr>
  
  <p>Update:  2019 JUN 04</p>
  
  <p>I continue to research this problem with little success.  Though I've found nothing beyond Massimiliano Sartoretto's comment stating the proxies are only for development servers, I've removed the proxy and am attempting to address the external API by other means.</p>
  
  <p>At present, I've configured the Content Security Policy to address the Cross-Origin Resource sharing, and I'm using Express to redirect the API call using the following code:</p>
  
  <pre><code>    app.get('/api/test', function(req, res) {
        request.get({
          url: 'https://markwilx-api.herokuapp.com/api/test' 
        }, function(error, response, body) {
          if(!error &amp;&amp; response.statusCode == 200) {
            res.send(body);
          }
        });
      });
  </code></pre>
  
  <p>Once again, this works seamlessly on my development environment (the front-end server running on localhost and the back-end server running on Heroku), but it fails once uploaded to Heroku.</p>
  
  <p>The front-end server running on Heroku gives the following errors when the API is called:</p>
  
  <pre><code>Jun 04 05:08:02 markwilx heroku/router: at=info method=GET path="/api/test" host=www.markwilx.com request_id=2f789dad-7161-4269-bf92-64db8060eadd fwd="184.170.243.167" dyno=web.1 connect=0ms service=10ms status=500 bytes=404 protocol=https 
  Jun 04 05:08:02 markwilx app/web.1: ReferenceError: request is not defined 
  Jun 04 05:08:02 markwilx app/web.1:     at /app/server.js:35:3 
  Jun 04 05:08:02 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
  Jun 04 05:08:02 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/route.js:137:13) 
  Jun 04 05:08:02 markwilx app/web.1:     at Route.dispatch (/app/node_modules/express/lib/router/route.js:112:3) 
  Jun 04 05:08:02 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
  Jun 04 05:08:02 markwilx app/web.1:     at /app/node_modules/express/lib/router/index.js:281:22 
  Jun 04 05:08:02 markwilx app/web.1:     at Function.process_params (/app/node_modules/express/lib/router/index.js:335:12) 
  Jun 04 05:08:02 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/index.js:275:10) 
  Jun 04 05:08:02 markwilx app/web.1:     at SendStream.error (/app/node_modules/serve-static/index.js:121:7) 
  Jun 04 05:08:02 markwilx app/web.1:     at emitOne (events.js:116:13) 
  Jun 04 05:08:07 markwilx heroku/router: at=info method=GET path="/api/test" host=www.markwilx.com request_id=99922c46-a529-4f7e-8190-670cedf3a33d fwd="184.170.243.167" dyno=web.1 connect=0ms service=5ms status=500 bytes=404 protocol=https 
  Jun 04 05:08:07 markwilx app/web.1: ReferenceError: request is not defined 
  Jun 04 05:08:07 markwilx app/web.1:     at /app/server.js:35:3 
  Jun 04 05:08:07 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
  Jun 04 05:08:07 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/route.js:137:13) 
  Jun 04 05:08:07 markwilx app/web.1:     at Route.dispatch (/app/node_modules/express/lib/router/route.js:112:3) 
  Jun 04 05:08:07 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
  Jun 04 05:08:07 markwilx app/web.1:     at /app/node_modules/express/lib/router/index.js:281:22 
  Jun 04 05:08:07 markwilx app/web.1:     at Function.process_params (/app/node_modules/express/lib/router/index.js:335:12) 
  Jun 04 05:08:07 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/index.js:275:10) 
  Jun 04 05:08:07 markwilx app/web.1:     at SendStream.error (/app/node_modules/serve-static/index.js:121:7) 
  Jun 04 05:08:07 markwilx app/web.1:     at emitOne (events.js:116:13) 
  </code></pre>
  
  <p>I'll continue providing updates as I work to resolve this problem.</p>