En aquesta secció, aprendrem a desenvolupar un microservei simple utilitzant una tecnologia popular com Spring Boot (Java) o Express (Node.js). Ens centrarem en la creació d'un servei RESTful que ofereixi operacions bàsiques de CRUD (Crear, Llegir, Actualitzar, Eliminar) sobre un recurs senzill, com ara "usuaris".
Objectius d'Aprenentatge
- Comprendre els passos bàsics per crear un microservei.
- Implementar operacions CRUD en un microservei.
- Configurar i executar el microservei.
Requisits Previs
- Coneixements bàsics de programació en Java o JavaScript.
- Entendre els conceptes bàsics de RESTful APIs.
Estructura del Tema
Configuració del Projecte
Spring Boot (Java)
-
Crear un nou projecte Spring Boot:
- Utilitza Spring Initializr (https://start.spring.io/) per generar un projecte amb les següents dependències:
- Spring Web
- Spring Data JPA
- H2 Database (per a una base de dades en memòria)
- Utilitza Spring Initializr (https://start.spring.io/) per generar un projecte amb les següents dependències:
-
Estructura del projecte:
src/main/java/com/example/microservice/ ├── MicroserviceApplication.java ├── controller/ ├── model/ └── repository/
Express (Node.js)
-
Crear un nou projecte Node.js:
- Inicialitza un nou projecte amb
npm init
. - Instal·la les dependències necessàries:
npm install express body-parser mongoose
- Inicialitza un nou projecte amb
-
Estructura del projecte:
microservice/ ├── app.js ├── controllers/ ├── models/ └── routes/
Creació del Model
Spring Boot (Java)
- Crear la classe
User
dins del paquetmodel
:package com.example.microservice.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private String email; // Getters and Setters }
Express (Node.js)
- Crear el model
User
dins de la carpetamodels
:const mongoose = require('mongoose'); const UserSchema = new mongoose.Schema({ name: String, email: String }); module.exports = mongoose.model('User', UserSchema);
Implementació del Controlador
Spring Boot (Java)
- Crear la classe
UserController
dins del paquetcontroller
:package com.example.microservice.controller; import com.example.microservice.model.User; import com.example.microservice.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/users") public class UserController { @Autowired private UserRepository userRepository; @GetMapping public List<User> getAllUsers() { return userRepository.findAll(); } @PostMapping public User createUser(@RequestBody User user) { return userRepository.save(user); } @GetMapping("/{id}") public User getUserById(@PathVariable Long id) { return userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User not found")); } @PutMapping("/{id}") public User updateUser(@PathVariable Long id, @RequestBody User userDetails) { User user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User not found")); user.setName(userDetails.getName()); user.setEmail(userDetails.getEmail()); return userRepository.save(user); } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { User user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User not found")); userRepository.delete(user); } }
Express (Node.js)
-
Crear el controlador
userController.js
dins de la carpetacontrollers
:const User = require('../models/User'); exports.getAllUsers = async (req, res) => { try { const users = await User.find(); res.json(users); } catch (err) { res.status(500).json({ message: err.message }); } }; exports.createUser = async (req, res) => { const user = new User({ name: req.body.name, email: req.body.email }); try { const newUser = await user.save(); res.status(201).json(newUser); } catch (err) { res.status(400).json({ message: err.message }); } }; exports.getUserById = async (req, res) => { try { const user = await User.findById(req.params.id); if (user == null) { return res.status(404).json({ message: 'User not found' }); } res.json(user); } catch (err) { res.status(500).json({ message: err.message }); } }; exports.updateUser = async (req, res) => { try { const user = await User.findById(req.params.id); if (user == null) { return res.status(404).json({ message: 'User not found' }); } if (req.body.name != null) { user.name = req.body.name; } if (req.body.email != null) { user.email = req.body.email; } const updatedUser = await user.save(); res.json(updatedUser); } catch (err) { res.status(400).json({ message: err.message }); } }; exports.deleteUser = async (req, res) => { try { const user = await User.findById(req.params.id); if (user == null) { return res.status(404).json({ message: 'User not found' }); } await user.remove(); res.json({ message: 'User deleted' }); } catch (err) { res.status(500).json({ message: err.message }); } };
-
Crear les rutes
userRoutes.js
dins de la carpetaroutes
:const express = require('express'); const router = express.Router(); const userController = require('../controllers/userController'); router.get('/users', userController.getAllUsers); router.post('/users', userController.createUser); router.get('/users/:id', userController.getUserById); router.put('/users/:id', userController.updateUser); router.delete('/users/:id', userController.deleteUser); module.exports = router;
-
Configurar l'aplicació a
app.js
:const express = require('express'); const bodyParser = require('body-parser'); const mongoose = require('mongoose'); const userRoutes = require('./routes/userRoutes'); const app = express(); app.use(bodyParser.json()); mongoose.connect('mongodb://localhost:27017/microservice', { useNewUrlParser: true, useUnifiedTopology: true }); app.use('/api', userRoutes); app.listen(3000, () => { console.log('Server is running on port 3000'); });
Configuració del Repositori
Spring Boot (Java)
- Crear la interfície
UserRepository
dins del paquetrepository
:package com.example.microservice.repository; import com.example.microservice.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { }
Express (Node.js)
- No es necessita una configuració addicional per al repositori, ja que Mongoose s'encarrega de la persistència de dades.
Execució i Prova del Microservei
Spring Boot (Java)
-
Executar l'aplicació:
- Executa la classe
MicroserviceApplication
que conté el mètodemain
.
- Executa la classe
-
Provar el microservei:
- Utilitza una eina com Postman per fer peticions HTTP a les rutes
/users
.
- Utilitza una eina com Postman per fer peticions HTTP a les rutes
Express (Node.js)
-
Executar l'aplicació:
node app.js
-
Provar el microservei:
- Utilitza una eina com Postman per fer peticions HTTP a les rutes
/api/users
.
- Utilitza una eina com Postman per fer peticions HTTP a les rutes
Exercicis Pràctics
-
Afegir un nou camp al model
User
:- Afegir un camp
age
al modelUser
i actualitzar les operacions CRUD per gestionar aquest nou camp.
- Afegir un camp
-
Implementar validacions:
- Afegir validacions per assegurar que el camp
email
sigui únic i tingui un format vàlid.
- Afegir validacions per assegurar que el camp
-
Crear un nou microservei:
- Desenvolupar un nou microservei per gestionar un altre recurs, com ara "productes", seguint els mateixos passos.
Conclusió
En aquesta secció, hem après a desenvolupar un microservei simple amb operacions CRUD utilitzant Spring Boot i Express. Hem configurat el projecte, creat el model, implementat el controlador, configurat el repositori i provat el microservei. Els exercicis pràctics proporcionats ajudaran a reforçar els conceptes apresos i a adquirir més experiència en el desenvolupament de microserveis.
Curs de Microserveis
Mòdul 1: Introducció als Microserveis
- Conceptes Bàsics de Microserveis
- Avantatges i Desavantatges dels Microserveis
- Comparació amb Arquitectura Monolítica
Mòdul 2: Disseny de Microserveis
- Principis de Disseny de Microserveis
- Descomposició d'Aplicacions Monolítiques
- Definició de Bounded Contexts