This is an old revision of the document!


Sesiuna 2 - Git. Rest API. Javascript. NodeJS

Am atins urmatoarele subiecte:

  • Introducere in Git
  • Strategii de Git Branching
  • REST Api
  • JavaScript

Materiale Online

Resursele pentru a doua sedinta, adica prezentarea PDF si inregistrarile video, pot fi gasite in acest folder de Gdrive

Activitate Practica

HTTP Rest API

Representational State Transfer (REST) este un stil arhitectural modern care defineste modul in care interactioneaza serviciile web. Acesta se bazeaza pe cereri HTTP (e.g.: GET, POST, PUT, DELETE) pentru a manipula informatia si pe media-types (e.g.: JSON) pentru a stabili cum arata informatia transferata.

Un API de tip REST este un serviciu Web care permite interactiunea prin mecanisme REST. Backendul pe care noi il vom dezvolta la laborator va fi un astfel de API.

Familiarizare Javascript

NodeJS este un mediu de rulare pentru Javascript bazat pe motorul V8 de la Chrome. Acesta permite rularea scripturilor de JS pe calculator, fara sa fie nevoie de browser.

Deoarece backendul si frontendul vor fi realizate folosind tehnologii care se bazeaza pe Javascript, este elementar sa cunoasteti acest limbaj. Javascript este un limbaj de scripting cu o sintaxa foarte usoara, asemanatoare celei din C. Va prezentam mai jos cateva particularitati ale limbajului:

  • JS este un limbaj slab tipat. Variabilele sunt definite nu cu tipuri, dar cu let sau const
  • Functiile nu au un tip de retur si de asemenea nici parametrii nu au tipul atasat
  • Functiile pot fi definite folosind keyword-ul function sau folosind arrow functions
function myFunc(x) {console.log(x)};
 
// este identic cu
 
const myFuncArrow = (x) => console.log(x);
 
myFunc(3); //3
myFuncArrow(3); //3
  • deoarece JS este un limbaj interpretat, nu conteaza ordinea in care sunt definite functiile. Totusi, este indicat sa fiti cat mai organizati in cod
  • JS nu are nevoie de o functie de main ca sa ruleze. Codul dintr-un fisier .js va rula in momentul in care scriptul este apelat
const constanta = 'abc';
let variabila = 3;
 
function adauga (x, y, z) {
  if (x === 'abc') {
    y = y + z;
  }
  return  y;
}
 
const rezultat = adauga(constanta, variabila, 10);
 
console.log(rezultat);
  • in JS exista doua tipuri de egalitate: == si ===. Primul tip de egalitate nu tine cont de tipurile variabirelor comparate, in timp ce al doilea tip este mai strict.
const a = 10; //a este numar
const b = '10'; //b este sir de caractere
 
console.log(a == b); //true
console.log(a === b); //false
 
const c = 'abc';
const d = 'abc';
 
console.log(c == d); //true
console.log(c === d); //true
 
const fals = false; //boolean
const str = ''; //string
const zero = 0; //number
 
console.log(fals == str); //true
console.log(fals == zero); //true
console.log(str == zero); //true
 
console.log(fals === str); //false
console.log(fals === zero); //false
console.log(str === zero); //false
  • JS este un limbaj semi-oop. Cu toate ca are concepte precum obiecte si clase (partial), principiile OOP nu se regasesc in totalitate
  • Vectorii sunt declarati cu paranteze drepte [ ] si obiectele cu paranteze acolade { }
  • Obiectele in JS sunt combinatii de chei valori, unde valorile pot fi orice: variabile, vectori, obiecte si chiar functii
  • Accesul la elementele dintr-un obiect se face in doua moduri:
const obj = {a:1, b:2};
 
console.log(obj.a); //1
console.log(obj['b']); //2
  • Deoarece JS opereaza cu obiecte, exista doua tipuri de copiere: prin referinta, implicit si prin valoare
const obj1 = {a:2};
const obj2 = obj1; // copiere prin referinta
 
obj2.a = 5;
console.log(obj1); // {a:5} -> valoarea s-a modificat si in obiectul original
 
const obj3 = Object.assign({}, obj1); // copiere prin valoare, incomplet pentru nivele mai adanci
 
obj3.a = 10;
console.log(obj1); // {a:5} -> valoarea nu s-a modificat
 
const obj4 = {...obj1} // copiere prin valoare (modern, folosind spread operator, ES6, dar incomplet pentru nivele mai adanci)
 
obj4.a = 9772;
console.log(obj1); // {a:5} -> valoarea nu s-a modificat
 
const obj5 = JSON.parse(JSON.stringify(obj1)); // copiere prin valoare completa
 
obj5.a = ['ana', 'are', 'mere'];
console.log(obj1); // {a:5} -> valoarea nu s-a modificat
  • JS este un limbaj functional. Prezinta concepte precum metode functionale (map, filter, reduce) si functii curry (callback-uri)
const arr = [1, 2, 3, 4];
console.log(arr.map(x => x*2)); //2 4 6 8
 
const obj = { a:2, b:3, c: (x, y) => console.log(x + y)}
console.log(obj.c(obj.a, obj['b'])); //5
 
const func1 = (x, cb) => cb(x);
const func2 = y => console.log(y);
 
func1(3, func2); //3

Familiarizare NodeJS

Prezentare pe scurt

NodeJS este un ecosistem de Javascript care permite folosirea limbajului Javascript pe partea de server. Este bazat pe motorul V8 de la Chrome, ruleaza pe un singur fir de executie si este asincron, utilizand o bucla de evenimente pentru a executa operatiile cat mai rapid.

Structura unui proiect in NodeJS

Module

Un proiect de Node este structurat in module. Fiecare fisier Javascript din componenta unui proiect este considerat un modul. Puteti sa faceti analogia cu fisierele .c din C sau cu clasele din Java.

Un modul poate fi importat de catre oricare alt modul (adica fisier .js), folosind keyword-ul require si calea relativa catre el. Un modul poate expune informatii in exterior folosind proprietatea exports a obiectului global module.

Se pot exporta oricate variabile sau functii. Chiar daca se exporta doar o functie, ca in exemplul urmator, este indicat sa o puneti intr-un obiect atunci cand o exportati

const sayHello = () => {  console.log("Hello world!");  }
module.exports = {
  sayHello
}
/*
module.exports = { sayHello } e identic cu
 
const objForExport = { sayHello: sayHello };
module.exports = objForExport;
*/

Atunci cand creati un obiect, daca cheia si valoarea au aceeasi denumire, se poate scrie doar numele cheii, fara sa se mai puna : si valoarea

modul1.js
const a = 2;
const b = 3;
const getA = () => { return a; }
const getB = () => { return b; }
module.exports = {
  getA
};
// pentru oricine va importa acest modul, singurul lucru la care va avea acces va fi functia "getA"
modul2.js
const myModule = require('./modul1.js');
 
const a_from_module_1 = myModule.getA();
console.log(a_from_module_1); //2
 
const b_from_module_1 = myModule.getB(); //ReferenceError! 

Pachete

Asa cum in alte limbaje se pot folosi biblioteci externe pentru diverse functionalitati ce sunt deja implementate (exemplu, stdio.h in C pentru I/O) si in Node se pot folosi pachete.

Pachetele sunt module instalate din surse externe. Pentru a instala un pachet se foloseste NPM - node package manager in terminal.

Pentru a putea instala pachete intr-un proiect, este nevoie ca aceasta sa fie initializat. Pentru a initializa un proiect de node, este nevoie sa rulati comanda

npm init

In urma rularii acestei comenzi se va crea un fisier, package.json. Acest fisier are rolul de a retine informatii cu privire la proiect si la dependentele sale.

Daca vreti sa rulati proiectul pe o alta masina, este nevoie sa va instalati local toate pachetele pe care le folositi in proiect. Puteti sa le instalati pe fiecare de mana, sau puteti sa va folositi de package.json si ele vor fi instalate automat

Pe langa dependente, in package.json sunt retinute si informatii cu privire la proiect (autor, repository, descriere) precum si scripturi de rulare si testare. Puteti asocia partea de scripts din package.json cu un Makefile.

Dupa ce ati initializat proiectul, puteti incepe sa instalati pachete. Pentru a instala un pachet, se executa comanda urmatoare:

npm install nume_pachet --save

Dupa ce instalati un pachet, se vor crea folderul node_modules si fisierul package-lock.json. In folder se afla toate pachetele instalate. In fisier se retine versiunea exacta a pachetului cu care se lucreaza.

Niciodata sa nu stergeti package-lock.json. De asemenea, acesta trebuie obligatoriu inclus in git.

Pentru a utiliza un pachet instalat, se foloseste tot keyword-ul require, insa se scrie doar numele pachetului, nu si calea catre locul unde a fost descarcat, aceasta deducandu-se automat din node_modules.

//presupunem ca am instalat inainte pachetul fictiv my-awesome-package
 
const myAwesomePackage = require('my-awesome-package');
//do stuff

Pentru a vedea cum se utilizeaza un pachet, este necesar sa cititi pagina acestuia de pe NPM sau de pe site-ul pachetului, daca exista. De obieci, documentatiile sunt cuprinzatoare.

Rularea unui API

Pentru a rula un API de Node, este nevoie sa definiti un fisier de start. Acest fisier trebuie sa includa apoi referinte catre celelalte fisiere ce fac parte din proiect, atat direct, cat si indirect (e.g. start face referire catre modulul 1 iar modulul 1 face referire catre modulul 2).

Exemplu de API minimal cu express:

start.js
const express = require('express');
 
const app = express();
 
app.get('/', (req, res) => {
    res.send("Hello world!");
});
 
app.listen(3000);

Daca doriti sa utilizati scripturi de npm, va trebui sa includeti referinta catre fisierul de start si in package.json:

package.json
{
  "name": "lab2",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node start.js"
  },
  "dependencies": {
    "express": "~4.16.1"
  }
}

Pentru a rula serverul, executati comanda:

npm run start

Atunci cand dezvoltati, va recomandam sa folositi pachetul Nodemon. Acesta urmareste modificari in cod si reporneste automat serverul. In cazul in care vreti sa folositi nodemon, va trebui sa inlocuiti node cu nodemon in package.json.

moby/backend/02.1595254993.txt.gz · Last modified: 2020/07/20 17:23 by alexandru.hogea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0