Backend
Que el frontend no s'aturi mentre el backend no hi és
Acordeu el contracte de l'API el primer dia, treballeu contra una API falsa (un mock) i, quan el backend estigui llest, canvieu una sola línia. Aquí teniu un generador que funciona al navegador, sense compte ni límits, i la guia per desplegar a virtech.
Tres maneres de fer un mock
No són excloents: moltes vegades es comença per la primera i es passa a la segona quan l'equip de frontend necessita un servidor de veritat.
Font de dades falsa
Una implementació Fake de la interfície que fa servir l'app. És el més ràpid per començar la UI i el que feu servir als tests unitaris.
json-server
Una API completa a partir d'un db.json: GET, POST, PUT, PATCH i DELETE, filtres, paginació i relacions. Els canvis es desen al fitxer. Serveix per a tot l'equip i per al mòbil.
Prism + OpenAPI
Un mock que respon segons el contracte i valida les peticions. Ideal per als serveis entre equips: el fitxer OpenAPI és l'acord entre tots dos.
Generador
Descriviu els recursos i en sortirà tot
Les dades es generen al vostre navegador i no s'envien enlloc. El mateix esquema dona sempre les mateixes dades, cosa que va bé per als tests.
Un recurs per línia, sense sagnar, i els seus camps a sota, sagnats: nom: tipus. Un ref enllaça amb un altre recurs (stationId: ref stations).
idint 0-20number 0-40booltextnameemailaddresslatlngdatedatetimeenum A|Burlref recurs
Amb Node.js instal·lat, a la carpeta del fitxer:
npx json-server@0.17.4 --watch db.json --port 8080 --host 0.0.0.0
Ja teniu GET /stations, GET /stations/1, POST, PUT, PATCH i DELETE, filtres (?status=IN_SERVICE, ?electric_gte=1), paginació (?_page=1&_limit=10) i relacions (/stations/1/favorites, /favorites?_expand=station).
El contracte, per compartir amb l'equip que consumirà el vostre servei. Obriu-lo a editor.swagger.io per veure'l i, per tenir-ne un mock que valida les peticions:
npx @stoplight/prism-cli mock -h 0.0.0.0 -p 8080 openapi.yaml
Al paquet de dades del projecte Android. El ViewModel rep un StationsDataSource: avui li passeu el Fake, demà el que crida l'API amb Retrofit.
A lib/data/ del projecte Flutter. El BLoC rep un StationsDataSource des del locator (get_it o el que feu servir).
Del mock al backend real, canviant una línia
La clau és que la UI no sàpiga d'on surten les dades. Depèn d'una interfície i, en arrencar, l'app decideix quina implementació hi posa.
// build.gradle.kts: buildConfigField("boolean", "USE_MOCK", "true") al build de debug
val dataModule = module {
single<StationsDataSource> {
if (BuildConfig.USE_MOCK) FakeStationsDataSource()
else HttpStationsDataSource(baseUrl = "http://10.0.2.2:8080/")
}
viewModel { StationsViewModel(get()) }
}
const useMock = bool.fromEnvironment('USE_MOCK', defaultValue: true);
const apiUrl = String.fromEnvironment('API_URL', defaultValue: 'http://10.0.2.2:8080');
void setupLocator() {
locator.registerLazySingleton<StationsDataSource>(
() => useMock ? FakeStationsDataSource() : HttpStationsDataSource(apiUrl),
);
}
// flutter run --dart-define=USE_MOCK=false --dart-define=API_URL=http://nattech.fib.upc.edu:40330
localhost del vostre ordinador és 10.0.2.2. El simulador d'iOS fa servir localhost. Un mòbil de veritat a la mateixa wifi fa servir la IP local de l'ordinador (per això el --host 0.0.0.0). Fora de casa, virtech.virtech, el núvol privat de la FIB
Un servei d'autoservei de màquines virtuals per a les assignatures que el demanen, a virtech.fib.upc.edu. Els comptes us els donen els professors.
- Màquines Ubuntu amb l'usuari
alumne, que pot fer servirsudo. Sou responsables de tot el que hi passi. - El nombre de màquines i la seva mida els fixa la quota de l'assignatura. No hi ha tallafocs.
- No hi ha còpies de seguretat i s'esborren al final del quadrimestre. El codi, a GitHub; la configuració, documentada.
- Si perdeu l'accés a una màquina, no es pot recuperar: s'esborra i se'n crea una altra. Un motiu més per tenir la instal·lació escrita en un script.
Només xarxa de la FIB
Accessible des del campus o des de casa amb la VPN de la UPC (UPClink). Però la VPN és personal i només admet una connexió: no podeu tenir alhora l'ordinador i el mòbil, ni donar l'app a ningú de fora.
Plantilla sense VPN
Té 10 ports oberts a Internet a través de nattech.fib.upc.edu, i SSH des de la UPC o amb VPN. Qualsevol mòbil hi arriba, també els dels stakeholders.
Crear la màquina i posar-hi el servei
- VMs → +, trieu la plantilla, poseu-hi un nom i la contrasenya de l'usuari, i Create. Espereu que passi de DEPLOYING a RUNNING.
- Obriu la Consola (VNC) i inicieu sessió. El missatge de benvinguda us diu la IP i els ports. El podeu tornar a veure amb
/etc/update-motd.d/99-info-nat. - Des d'ara, millor per SSH (des de la UPC o amb VPN): calculeu l'ordre a sota.
- Arrenqueu el servei escoltant a
0.0.0.0i a un port del 8080 al 8089. Si escolta alocalhost, des de fora no s'hi arriba. - Proveu-lo des de fora amb el port públic:
http://nattech.fib.upc.edu:40330.
La que surt a virtech o al missatge de benvinguda.
Com es calculen els ports
Totes les màquines surten a Internet per la mateixa adreça, nattech.fib.upc.edu, i cadascuna té el seu rang de ports segons l'últim número de la IP (172.16.4.XXX):
- SSH: port
22000 + XXX. - Serveis: del port
40000 + XXX·10en endavant, deu ports seguits que van al 8080-8089 de la màquina.
Instal·lar Node i deixar el mock en marxa
# Node.js 22
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
# des del vostre ordinador (campus o VPN): pugeu el db.json
ssh -p 22033 alumne@nattech.fib.upc.edu mkdir -p api
scp -P 22033 db.json alumne@nattech.fib.upc.edu:~/api/
# a la màquina
cd ~/api && npm install json-server@0.17.4
npx json-server --watch db.json --port 8080 --host 0.0.0.0
Perquè continuï funcionant quan tanqueu la sessió, feu-ne un servei:
# /etc/systemd/system/api.service
[Unit]
Description=API PES
After=network.target
[Service]
User=alumne
WorkingDirectory=/home/alumne/api
ExecStart=/home/alumne/api/node_modules/.bin/json-server --watch db.json --port 8080 --host 0.0.0.0
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now api
Amb el vostre backend és igual: canvieu l'ExecStart per l'ordre que l'arrenca.
Com comprovo que la connexió funciona, abans de tenir cap servei?
A la màquina, nc -l -p 8080. Al vostre ordinador, nc nattech.fib.upc.edu 40330 (amb el vostre port) i escriviu qualsevol cosa: ha d'aparèixer a la màquina.
Per què no em respon el ping?
Per com està muntat el NAT, el ping no funciona des de fora de la xarxa de les màquines, ni tan sols amb VPN. Feu servir curl o nc.
Puc entrar per SSH des de casa sense VPN?
No. Per seguretat, l'SSH des de fora de la UPC només funciona amb la VPN. Els 10 ports de serveis sí que estan oberts a tothom.
He oblidat la contrasenya de la màquina.
No es pot recuperar: esborreu la màquina i creeu-ne una de nova. La contrasenya de virtech (no la de la màquina) es canvia al menú d'usuari → Settings → Change password.
L'app mòbil i l'HTTP sense xifrar
nattech serveix HTTP, no HTTPS. Android (des de la versió 9) i iOS bloquegen aquest trànsit per defecte, i la crida falla sense gaires pistes. Permeteu-lo només per a aquest domini.
<!-- res/xml/network_security_config.xml (a Flutter: android/app/src/main/res/xml/) -->
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">nattech.fib.upc.edu</domain>
<domain includeSubdomains="false">10.0.2.2</domain>
</domain-config>
</network-security-config>
<!-- AndroidManifest.xml -->
<application
android:networkSecurityConfig="@xml/network_security_config"
... >
<!-- ios/Runner/Info.plist -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>nattech.fib.upc.edu</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
Les contrasenyes viatgen en clar per HTTP. Per a PES n'hi ha prou amb l'excepció per domini, però no hi poseu contrasenyes reals i expliqueu-ho a la documentació com a limitació coneguda.