mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Example to add custom reverse proxy like in webpack-dev-server (#2660)
* add with-custom-reverse-proxy example * cleanup * cleanup package.json * fix linting errors * more linting errors
This commit is contained in:
parent
e2fb50c301
commit
c87b471b22
7
examples/with-custom-reverse-proxy/.babelrc
Normal file
7
examples/with-custom-reverse-proxy/.babelrc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"next/babel",
|
||||||
|
"latest",
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
}
|
3
examples/with-custom-reverse-proxy/.eslintrc
Normal file
3
examples/with-custom-reverse-proxy/.eslintrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": "standard"
|
||||||
|
}
|
52
examples/with-custom-reverse-proxy/README.md
Normal file
52
examples/with-custom-reverse-proxy/README.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
## The idea behind the example
|
||||||
|
|
||||||
|
This example applies this gist https://gist.github.com/jamsesso/67fd937b74989dc52e33 to Nextjs and provides:
|
||||||
|
|
||||||
|
* Reverse proxy in development mode by add `http-proxy-middleware` to custom server
|
||||||
|
* NOT a recommended approach to production scale (hence explicit dev flag) as we should scope proxy as outside UI applications and have separate web server taking care of that.
|
||||||
|
|
||||||
|
Sorry for the extra packages. I belong to the minority camp of writing ES6 code on Windows developers. Essentially you only need `http-proxy-middleware` on top of bare-bone Nextjs setup to run this example.
|
||||||
|
|
||||||
|
## How to run it
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i; npm run build; npm run dev;
|
||||||
|
```
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
Take any random query string to the index page and does a GET to `/api/<query string>` which gets routed internally to `https://swapi.co/api/<query string>`, or any API endpoint you wish to configure through the proxy.
|
||||||
|
|
||||||
|
## Expectation
|
||||||
|
|
||||||
|
```
|
||||||
|
/api/people/2 routed to https://swapi.co/api/people/2
|
||||||
|
Try Reset
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "C-3PO",
|
||||||
|
"height": "167",
|
||||||
|
"mass": "75",
|
||||||
|
"hair_color": "n/a",
|
||||||
|
"skin_color": "gold",
|
||||||
|
"eye_color": "yellow",
|
||||||
|
"birth_year": "112BBY",
|
||||||
|
"gender": "n/a",
|
||||||
|
"homeworld": "https://swapi.co/api/planets/1/",
|
||||||
|
"films": [
|
||||||
|
"https://swapi.co/api/films/2/",
|
||||||
|
"https://swapi.co/api/films/5/",
|
||||||
|
"https://swapi.co/api/films/4/",
|
||||||
|
"https://swapi.co/api/films/6/",
|
||||||
|
"https://swapi.co/api/films/3/",
|
||||||
|
"https://swapi.co/api/films/1/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://swapi.co/api/species/2/"
|
||||||
|
],
|
||||||
|
"vehicles": [],
|
||||||
|
"starships": [],
|
||||||
|
"created": "2014-12-10T15:10:51.357000Z",
|
||||||
|
"edited": "2014-12-20T21:17:50.309000Z",
|
||||||
|
"url": "https://swapi.co/api/people/2/"
|
||||||
|
}
|
||||||
|
```
|
25
examples/with-custom-reverse-proxy/package.json
Normal file
25
examples/with-custom-reverse-proxy/package.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "with-custom-reverse-proxy",
|
||||||
|
"engines": {
|
||||||
|
"node": "7.x.x"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.15.3",
|
||||||
|
"next": "^3.0.1-beta.13",
|
||||||
|
"react": "^15.5.4",
|
||||||
|
"react-dom": "^15.5.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-preset-latest": "^6.24.1",
|
||||||
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
|
"babel-register": "^6.24.1",
|
||||||
|
"cross-env": "^5.0.1",
|
||||||
|
"http-proxy-middleware": "^0.17.4"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "cross-env NODE_ENV=development PORT=3000 node server.js",
|
||||||
|
"build": "next build",
|
||||||
|
"prod": "cross-env NODE_ENV=production PORT=3000 node server.js"
|
||||||
|
}
|
||||||
|
}
|
45
examples/with-custom-reverse-proxy/pages/index.js
Normal file
45
examples/with-custom-reverse-proxy/pages/index.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default class extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
this.state = { response: '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getInitialProps ({ pathname, query }) {
|
||||||
|
return {
|
||||||
|
pathname,
|
||||||
|
query,
|
||||||
|
queryString: Object.keys(query).join('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount () {
|
||||||
|
const response = JSON.stringify(
|
||||||
|
await window
|
||||||
|
.fetch(`/api/${this.props.queryString}`)
|
||||||
|
.then(response => response.json().then(data => data)),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
this.setState({ response })
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<content>
|
||||||
|
<p>
|
||||||
|
/api/{this.props.queryString} routed to https://swapi.co/api/{this.props.queryString}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href='?people/2'>Try</a>
|
||||||
|
|
||||||
|
<a href='/'>Reset</a>
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
{this.state.response ? this.state.response : 'Loading...'}
|
||||||
|
</pre>
|
||||||
|
</content>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
50
examples/with-custom-reverse-proxy/server.es6.js
Normal file
50
examples/with-custom-reverse-proxy/server.es6.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
import express from 'express'
|
||||||
|
import next from 'next'
|
||||||
|
|
||||||
|
const devProxy = {
|
||||||
|
'/api': {
|
||||||
|
target: 'https://swapi.co/api/',
|
||||||
|
pathRewrite: {'^/api': '/'},
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const port = process.env.PORT || 3000
|
||||||
|
const env = process.env.NODE_ENV
|
||||||
|
const dev = env !== 'production'
|
||||||
|
const app = next({
|
||||||
|
dir: '.', // base directory where everything is, could move to src later
|
||||||
|
dev
|
||||||
|
})
|
||||||
|
|
||||||
|
const handle = app.getRequestHandler()
|
||||||
|
|
||||||
|
let server
|
||||||
|
app
|
||||||
|
.prepare()
|
||||||
|
.then(() => {
|
||||||
|
server = express()
|
||||||
|
|
||||||
|
// Set up the proxy.
|
||||||
|
if (dev && devProxy) {
|
||||||
|
const proxyMiddleware = require('http-proxy-middleware')
|
||||||
|
Object.keys(devProxy).forEach(function (context) {
|
||||||
|
server.use(proxyMiddleware(context, devProxy[context]))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default catch-all handler to allow Next.js to handle all other routes
|
||||||
|
server.all('*', (req, res) => handle(req, res))
|
||||||
|
|
||||||
|
server.listen(port, err => {
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
console.log(`> Ready on port ${port} [${env}]`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('An error occurred, unable to start the server')
|
||||||
|
console.log(err)
|
||||||
|
})
|
2
examples/with-custom-reverse-proxy/server.js
Normal file
2
examples/with-custom-reverse-proxy/server.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
require('babel-register')
|
||||||
|
module.exports = require('./server.es6.js')
|
Loading…
Reference in a new issue