==== Úkol ====
* Vyzkoušejte si vytvořit vlastní ExpressJS aplikaci ([[krouzek:nodejs|běží na NodeJS]]) - viz návod (1)
* Sami si najděte ''%%curl%%'' příkazy pro testování svých POST a GET endpointů, případně zkuste v Nástrojích pro vývojáře v prohlížeči.
* **Jak správně strukturovat ExpressJS projekt? Představte si, že bude mít endpointů třeba 100!** - viz návod (2)
* Teď ukládáme všechna data čistě do paměti (in-memory). Jaká je hlavní nevýhoda? Na jakou aplikaci je to v pořádku využít a kde by to již vadilo?
* Kam budeme směřovat? **Databáze**!
===== (1) ExpressJS aplikace =====
> Write a step-by-step tutorial how to create an ExpressJS application with two example routes, GET and POST interacting via JSON. Make that a POST game/ to create new game and GET game/:id to query the game state.
Sure, here's the step-by-step tutorial for creating an Express.js application with GET and POST routes in DokuWiki syntax:
===== Prerequisites: =====
* Node.js installed on your system.
* A basic understanding of JavaScript and HTTP concepts.
==== Step 1: Setting up your project ====
Create a new directory for your project and navigate to it in your terminal.
Initialize a new Node.js project by running the following command:
npm init
Follow the prompts to configure your project.
Install the Express.js framework:
npm install express --save
===== Step 2: Create your Express.js application =====
Create a new JavaScript file (e.g., ''app.js'') in your project directory.
Open ''app.js'' in your code editor and import Express:
const express = require('express');
const app = express();
const port = 3000; // You can choose any port you prefer
===== Step 3: Define your routes =====
Create a simple in-memory storage for game data. In a real application, you'd use a database.
const games = {};
let gameIdCounter = 1;
Create a POST route to create a new game. This route will accept JSON data and generate a unique game ID.
app.use(express.json())
app.post('/game', (req, res) => {
const newGameId = gameIdCounter++
const newGame = {
id: newGameId,
state: 'New', // You can initialize the state as needed
}
games[newGameId] = newGame
res.status(201).json(newGame)
})
Create a GET route to query the game state by ID.
app.get('/game/:id', (req, res) => {
const gameId = parseInt(req.params.id)
const game = games[gameId]
if (game) {
res.json(game)
} else {
res.status(404).json({ error: 'Game not found' })
}
})
===== Step 4: Start the Express server =====
Add the following code at the end of your ''app.js'' to start the server:
app.listen(port, () => {
echo "Server is running on port ${port}";
});
===== Step 5: Running your application =====
In your terminal, navigate to your project directory and run your Express application:
node app.js
Your Express app should now be running on the specified port (in this case, port 3000).
===== Step 6: Testing your routes =====
You can test your routes using tools like Postman, cURL, or by creating a simple front-end application.
* To create a new game, make a POST request to ''http://localhost:3000/game'' with a JSON body containing your game data.
* To query the game state, make a GET request to ''http://localhost:3000/game/:id'', replacing '':id'' with the actual game ID you want to retrieve.
That's it! You've created an Express.js application with two example routes (GET and POST) that interact via JSON to manage a simple game state. You can expand upon this foundation to build more complex applications with Express.js.
----
===== (2) Strukturování ExpressJS aplikace =====
> Write a beginner guide to structure a ExpressJS project. Explain idea of controller and model. Mention view but do not elaborate, as we're about to create API application only. In which folders to put the source files? Show example route file and controller.
===== Project Structure =====
**Project Root**: This is where your main application file (usually ''app.js'' or ''index.js'') is located.
**
Folders**:
* routes: Contains route files, where you define the endpoints and their corresponding controllers.
* controllers: Holds controller files, which contain the logic for handling requests and responses.
* models: Contains model files, which represent the data structure and interact with your database. Since you're building an API application, models can be used to define the structure of your data.
Here's a simplified example of how to structure an Express.js project:
my-express-app/
|-- app.js
|-- routes/
| |-- gameRoutes.js
|-- controllers/
| |-- gameController.js
|-- models/
| |-- gameModel.js
===== Controllers and Models =====
**Controllers**: Controllers handle the application's logic. They receive requests from the routes, process the data (if needed), and send a response back. In an API application, controllers are responsible for taking the input from the client, performing necessary actions, and sending a response (typically in JSON format) back to the client.
**Models**: Models define the structure and behavior of your data. In an API application, they can represent your data's schema. While you may not have a database in this specific example, models can still be used to define the structure of the data you'll be working with. They encapsulate the data-related logic and can be reused in different parts of your application.
===== Example Route File (gameRoutes.js) =====
const express = require('express');
const router = express.Router();
const gameController = require('../controllers/gameController');
// Define routes and their corresponding controller functions
router.post('/game', gameController.createGame);
router.get('/game/:id', gameController.getGame);
module.exports = router;
===== Example Controller (gameController.js) =====
const games = {}; // In-memory storage for game data
let gameIdCounter = 1;
const createGame = (req, res) => {
const newGameId = gameIdCounter++;
const newGame = {
id: newGameId,
state: 'New', // Initialize the state as needed
};
games[newGameId] = newGame;
res.status(201).json(newGame);
};
const getGame = (req, res) => {
const gameId = parseInt(req.params.id);
const game = games[gameId];
if (game) {
res.json(game);
} else {
res.status(404).json({ error: 'Game not found' });
}
};
module.exports = {
createGame,
getGame,
};
In this example, the ''gameRoutes.js'' file defines the API endpoints, while the ''gameController.js'' file contains the logic for handling these endpoints. The ''models'' directory would typically contain models for more complex applications with a database, but in this case, it can be used to define the structure of the game data.
This structure provides separation of concerns, making your project more organized and easier to maintain as it grows. The controller handles the application's logic, and the model can be extended to interact with a database if needed in the future.
-----