Artigo original: How To Make create-react-app work with a Node Back-end API
Esta é uma pergunta muito comum entre os novos desenvolvedores do React. É uma pergunta que eu tinha quando estava começando com o React e o Node.js. Neste breve exemplo, mostrarei como fazer com que o create-react-app
funcione com o back-end com o Node.js e o Express.
create-react-app
Crie um projeto usando create-react-app
.
npx create-react-app example-create-react-app-express
Crie um diretório /client
no diretório example-create-react-app-express
e mova todo o código boilerplate do React criado pelo create-react-app
para esse novo diretório client
.
cd example-create-react-app-express
mkdir client
O servidor com Node e Express
Crie um arquivo package.json
dentro do diretório raiz (example-create-react-app-express
) e copie o seguinte conteúdo:
{
"name": "example-create-react-app-express",
"version": "1.0.0",
"scripts": {
"client": "cd client && yarn start",
"server": "nodemon server.js",
"dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
},
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4"
},
"devDependencies": {
"concurrently": "^4.0.1"
}
}
Observe que estou usando concurrently
para executar a aplicação do React e o servidor ao mesmo tempo. O marcador –kill-others-on-fail
eliminará outros processos se um deles for encerrado com um código de status diferente de zero.
Instale o nodemon
globalmente e as dependências do servidor:
npm i nodemon -g
yarn
Crie um arquivo server.js
e copie o seguinte conteúdo:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/api/hello', (req, res) => {
res.send({ express: 'Hello From Express' });
});
app.post('/api/world', (req, res) => {
console.log(req.body);
res.send(
`I received your POST request. This is what you sent me: ${req.body.post}`,
);
});
app.listen(port, () => console.log(`Listening on port ${port}`));
Este é um servidor Express simples que será executado na porta 5000 e terá duas rotas de API: GET
- /api/hello
e POST
-/api/world
.
Nesse ponto, você pode executar o servidor Express com o seguinte comando (ainda dentro do diretório raiz):
node server.js
Agora, navegue até http://localhost:5000/api/hello
e você verá o seguinte:
Vamos testar a rota POST
quando criarmos a aplicação em React.
A aplicação em React
Agora, vá para o diretório do client
onde está a nossa aplicação em React.
Adicione a seguinte linha ao arquivo package.json
criado pelo create-react-app
.
"proxy": "http://localhost:5000/"
A chave para usar um servidor de back-end do Express com um projeto criado com create-react-app
é usar um proxy. Isso informa ao servidor de desenvolvimento do webpack para fazer proxy das nossas solicitações de API para o nosso servidor de API, já que o nosso servidor do Express está sendo executado em localhost:5000
.
Agora, modifique o ./client/src/App.js
para chamar o back-end da API Express. As alterações estão em negrito.
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
state = {
response: '',
post: '',
responseToPost: '',
};
componentDidMount() {
this.callApi()
.then(res => this.setState({ response: res.express }))
.catch(err => console.log(err));
}
callApi = async () => {
const response = await fetch('/api/hello');
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
return body;
};
handleSubmit = async e => {
e.preventDefault();
const response = await fetch('/api/world', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ post: this.state.post }),
});
const body = await response.text();
this.setState({ responseToPost: body });
};
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<p>{this.state.response}</p>
<form onSubmit={this.handleSubmit}>
<p>
<strong>Post to Server:</strong>
</p>
<input
type="text"
value={this.state.post}
onChange={e => this.setState({ post: e.target.value })}
/>
<button type="submit">Submit</button>
</form>
<p>{this.state.responseToPost}</p>
</div>
);
}
}
export default App;
Criamos o método callApi
para interagir com o caminho do GET
da API do Express. Depois, chamamos esse método em componentDidMount
e, por fim, definimos o estado para a resposta da API, que será "Hello From Express".
Observe que não usamos um URL totalmente qualificado http://localhost:5000/api/hello
para chamar nossa API, mesmo que nossa aplicação do React seja executada em uma porta diferente (3000). Isso se deve à linha do proxy
que adicionamos ao arquivo package.json
anteriormente.
Temos um formulário com uma única entrada. Quando enviado, chama handleSubmit
, que, por sua vez, chama o caminho POST
do Express API, salva a resposta no estado e exibe uma mensagem para o usuário: I received your POST request. This is what you sent me: [message from input].
Agora, abra o arquivo ./client/src/App.css
e modifique a classe .App-header
da seguinte forma (alterações em negrito)
.App-header {
...
min-height: 50%;
...
padding-bottom: 10px;
}
Executando a aplicação
Se o servidor ainda estiver em execução, interrompa-o pressionando Ctrl+C no terminal.
No diretório raiz do projeto, execute o seguinte:
yarn dev
Isso iniciará a aplicação do React e executará o servidor ao mesmo tempo.
Agora, navegue até http://localhost:3000
e você verá a aplicação do React exibindo a mensagem proveniente do nosso caminho GET
do Express. Legal!
Agora, digite algo no campo de entrada e envie o formulário. Você verá a resposta do caminho POST
do Express exibida logo abaixo do campo de entrada.
Por fim, dê uma olhada no seu terminal e verá a mensagem que enviamos do client, porque chamamos console.log
no corpo da solicitação no caminho POST
Express.
Implementação de produção no Heroku
Abra o server.js
e substitua pelo conteúdo a seguir:
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// API calls
app.get('/api/hello', (req, res) => {
res.send({ express: 'Hello From Express' });
});
app.post('/api/world', (req, res) => {
console.log(req.body);
res.send(
`I received your POST request. This is what you sent me: ${req.body.post}`,
);
});
if (process.env.NODE_ENV === 'production') {
// Serve any static files
app.use(express.static(path.join(__dirname, 'client/build')));
// Handle React routing, return all requests to React app
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
}
app.listen(port, () => console.log(`Listening on port ${port}`));
Abra o arquivo ./package.json
e adicione o seguinte à entrada de scripts
"start": "node server.js",
"heroku-postbuild": "cd client && npm install && npm install --only=dev --no-shrinkwrap && npm run build"
O Heroku executará o script start
por padrão e isso servirá à nossa aplicação. Em seguida, queremos instruir o Heroku a criar nossa aplicação do client. Fazemos isso com o script heroku-postbuild
.
Agora, vá até o Heroku (em inglês) e faça login (ou abra uma conta, se ainda não tiver uma).
Crie uma aplicação e dê um nome a ela.
Clique na aba Deploy e siga as instruções de implantação (que eu acho que são bastante autoexplicativas, não há motivo para repeti-las aqui).
É isso! Você pode abrir sua aplicação clicando no botão Open app, no canto superior direito do painel do Heroku da sua aplicação.
Outras opções de implementação
Escrevo sobre outras opções de implementação aqui:
Estrutura do projeto
Esta será a estrutura final do projeto:
Acesse o código completo no repositório do GitHub.
Obrigado pela leitura! Espero que você tenha gostado.
Você pode seguir o autor no Twitter, GitHub, Medium, LinkedIn ou em todos eles.
Esta postagem foi publicada originalmente no blog pessoal do autor.
Atualização em 25/08/19: o autor estava em processo de desenvolver uma aplicação para web de orações, chamada "My Quiet Time - A Prayer Journal". Para ver algumas capturas de tela de modelos, acesse o link a seguir: http://pc.cd/Lpy7. Se quiser saber mais sobre a aplicação, o autor deixou disponível o endereço no Twitter para dúvidas sobre a aplicação.