2

Trying to create server side API for the client application. The client is written completely on react. In development is served with webdevserver on port 3000. The server is listening on port 3001. I've added proxy to the package.json file of the client app as following:

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "devDependencies": {
    "react-scripts": "0.8.5"
  },
  "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "react-router": "^3.0.2",
    "superagent": "^3.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:3001/"
}

but once I am requesting the server API it fails:

import Request from 'superagent';

export function searchTasks(text, callback) {
  Request.get('http://localhost:3000/api/v1/tasks', response => {
    callback(response.body.Search);
  })
}

Response object is null. If I try to request API with 3001 port - everything works fine. It seems web-dev-server is not proxying the requests or, maybe, I missed some additional configuration options?

Andrei Tarutin
  • 684
  • 1
  • 10
  • 25
  • Did you try to do `/api/v1/tasks` instead, as the [docs](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development) suggests? Also, I notice you're using `superagent` instead of the `fetch` api - switching to the latter might help. – Kris Selbekk Feb 14 '17 at 14:01
  • tried different url, but the same issue – Andrei Tarutin Feb 14 '17 at 14:03
  • How about changing your `proxy` to `http://localhost:3001` (lose the last `/`)? – Kris Selbekk Feb 14 '17 at 14:10
  • Also tried but no luck – Andrei Tarutin Feb 14 '17 at 14:14
  • Regarding fetch: tried to use it but there appeared a lot of errors once I installed fetch and tried to use it. Suddenly there are a lot of libraries missed like net, dgram, tap etc. Can't figure out what is this. – Andrei Tarutin Feb 14 '17 at 14:15
  • Well, I was thinking fetch is some kind of third part package but it appeared to be a regular method in browsers. Now it works fine, but I wonder why it doesn't work with, for example, Request npm package? – Andrei Tarutin Feb 14 '17 at 14:38

1 Answers1

2

The reason this fails for you is because you're using superagent to do your requests. superagent sends the wrong Accept header for the create-react-app proxy to work correctly. According to the comments in the create-react-app documentation, the proxy setup uses some heuristics to deal with what should be sent to the history API and what should be proxied.

You can fix this most easily by adding .accept('json') to your request. That's done like so:

import Request from 'superagent';

export function searchTasks(text, callback) {
  Request.get('http://localhost:3000/api/v1/tasks')
    .accept('json')
    .end(response => callback(response.body.Search));
}

Another way is to use the fetch API. You can read more about it (and how to polyfill it for older browsers) in the documentation.

Kris Selbekk
  • 7,438
  • 7
  • 46
  • 73
  • Thank you for such a detailed explanation.It seems there is some issue with the code example you provided. It doesn't work and I don't know why. It just returns null in response. But I got the idea and used `request` npm package for the same purpose and changed the `Accept` header to be equal to `application/json` and it works fine. – Andrei Tarutin Feb 14 '17 at 21:12