Home SOFTWAREArhitektura modernih web aplikacija – Deo 3: Backend arhitektura: REST, GraphQL i gRPC

Arhitektura modernih web aplikacija – Deo 3: Backend arhitektura: REST, GraphQL i gRPC

REST, GraphQL i gRPC, uz praktične primere u Node.js-u

od itn
Arhitektura modernih web aplikacija

Dobrodošli u treći deo serijala na ITNetwork.rs! U prethodnim delovima smo postavili temelje sa monolitom i mikroservisima, a zatim istražili frontend arhitekture (SPA, SSR, SSG). Sada ulazimo u srce backend-a – kako servisi komuniciraju? Danas ćemo uporediti tri ključna API pristupa: REST, GraphQL i gRPC, uz praktične primere u Node.js-u.

Zašto je backend arhitektura ključna?

Backend je „mozak“ aplikacije:

  • Obrada logike
  • Komunikacija sa bazama
  • Integracija sa drugim servisima
  • API je ugovor između frontenda i backend-a

Loše dizajniran API = frustracija developera, spori frontend, teško održavanje.

1. REST (REpresentational State Transfer)

Definicija

Arhitektonski stil baziran na HTTP metodama i resursima.

GET    /api/users        → lista korisnika
GET    /api/users/123    → jedan korisnik
POST   /api/users        → kreiraj korisnika
PUT    /api/users/123    → ažuriraj korisnika
DELETE /api/users/123    → obriši korisnika
Ključni principi (prema Fielding-u)
Princip Objašnjenje
Resursi Sve je URI (npr. /users/123)
HTTP metode GET, POST, PUT, DELETE
Stateless Svaki zahtev je nezavisan
Cacheable Koristi Cache-Control
HATEOAS Hipermedija kao motor stanja aplikacije
Primer: REST API u Express.js
// routes/users.ts
import express from 'express';
const router = express.Router();

interface User {
  id: number;
  name: string;
  email: string;
}

let users: User[] = [
  { id: 1, name: 'Ana', email: 'ana@primer.rs' }
];

// GET /api/users
router.get('/', (req, res) => {
  res.json({
    data: users,
    links: {
      self: '/api/users',
      create: '/api/users'
    }
  });
});

// GET /api/users/1
router.get('/:id', (req, res) => {
  const user = users.find(u => u.id === +req.params.id);
  if (!user) return res.status(404).json({ error: 'Not found' });
  
  res.json({
    data: user,
    links: { self: `/api/users/${user.id}` }
  });
});

export default router;
2. GraphQL

Definicija

Query jezik za API-je – klijent tačno određuje šta želi.

# Umesto 3 REST poziva:
GET /users
GET /users/1/posts
GET /posts/5/comments

# Jedan GraphQL:
{
  user(id: 1) {
    name
    posts {
      title
      comments {
        text
        author { name }
      }
    }
  }
}
Prednosti
+ Objašnjenje
Nema over/under-fetchinga Dobijaš tačno ono što tražiš
Jedan endpoint /graphql
Introspekcija GraphiQL / GraphQL Playground
Verzionisanje nije potrebno Deprecate polja
Mane
Objašnjenje
N+1 problem Bez DataLoader-a – eksplozija upita
Keširanje teže HTTP cache ne radi direktno
Kompleksnost Resolveri, schema stitching
Primer: GraphQL sa Apollo Server
// server.ts
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import { readFileSync } from 'fs';

const typeDefs = readFileSync('./schema.graphql', 'utf-8');

const users = [{ id: 1, name: 'Ana' }];
const posts = [{ id: 1, userId: 1, title: 'GraphQL je super' }];

const resolvers = {
  Query: {
    user: (_: any, { id }: { id: number }) => users.find(u => u.id === id),
    users: () => users
  },
  User: {
    posts: (user: any) => posts.filter(p => p.userId === user.id)
  }
};

const server = new ApolloServer({ typeDefs, resolvers });
await server.start();

const app = express();
app.use('/graphql', expressMiddleware(server));

app.listen(4000, () => console.log('GraphQL na http://localhost:4000/graphql'));
schema.graphql:
type User {
  id: ID!
  name: String!
  posts: [Post!]
}

type Post {
  id: ID!
  title: String!
}

type Query {
  user(id: ID!): User
  users: [User!]
}
3. gRPC (Google Remote Procedure Call)

Definicija

Binaran protokol preko HTTP/2 – koristi Protocol Buffers (.proto fajlove).

// user.proto
syntax = "proto3";

service UserService {
  rpc GetUser (GetUserRequest) returns (User);
  rpc ListUsers (Empty) returns (UserList);
}

message GetUserRequest {
  int32 id = 1;
}

message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
}

message UserList {
  repeated User users = 1;
}
Prednosti
+ Objašnjenje
Brzina Binaran, HTTP/2, streaming
Tipizacija .proto → generiše kod
Streaming Server, client, bidirectional
Idealan za mikroservise Interna komunikacija
Mane
Objašnjenje
Browser podrška ograničena gRPC-Web ili proxy
Debug teži Ne čitaš JSON u browseru
Kriva učenja .proto sintaksa
Kada koristiti?
  • Mikroservisi (Node.js → Go → Python)
  • Real-time sistemi
  • Mobilne aplikacije (manji payload)

API Gateway – „ulazna kapija“ za sve

Bez obzira na backend tehnologiju, API Gateway je obavezan u mikroservisima.

Funkcija Alat
Rutiranje Kong, Traefik, Express Gateway
Autentifikacija OAuth2, JWT validation
Rate limiting Redis + Lua
Keširanje Varnish, Cloudflare
Logging & Tracing OpenTelemetry
Dijagram: API Gateway + Mikroservisi

API Gateway + MikroservisiPoređenje: REST vs GraphQL vs gRPC

Kriterijum REST GraphQL gRPC
Protokol HTTP/1.1 HTTP (obično) HTTP/2
Format JSON JSON Binaran (Proto)
Endpointi Mnogo Jedan Mnogo (po servisu)
Keširanje HTTP cache Teže Ne
Browser podrška gRPC-Web
Performanse ★★★ ★★★★ ★★★★★
Učenje ★★★★★ ★★★ ★★
Idealno za Web frontende Fleksibilne frontende Mikroservise
Praktični primer: Hibridni API

Velike kompanije koriste sve tri:

Slučaj Tehnologija
Public API (klijenti) REST ili GraphQL
Mobilna app GraphQL (manje podataka)
Interni servisi gRPC
Legacy integracija REST
Alati za rad sa API-jima
Namena Alat
REST test Postman, Insomnia
GraphQL IDE GraphiQL, Apollo Studio
gRPC test BloomRPC, grpcurl
Dokumentacija Swagger, Redoc, GraphQL Docs

Koji API izabrati?

Tip projekta Preporuka
Mali projekat, brzi start REST
SPA sa kompleksnim podacima GraphQL
Mikroservisi, performanse gRPC (interno)
Public API + mobilni GraphQL + REST
Enterprise sa legacy REST + API Gateway

Zlatno pravilo: Ne biraj tehnologiju zbog mode. Biraš je zbog problema koji rešava.

Šta dalje?

U četvrtom delu ulazimo u baze podataka:

  • Relacione vs NoSQL
  • Polyglot persistence
  • CQRS i Event Sourcing

Tvoj izazov

  1. Napravi REST + GraphQL API za TODO listu
  2. Uporedi veličinu responsa za:
    graphql
    { todos { id title } }

    vs REST /todos?fields=id,title

  3. Komentariši ispod: „Koji API koristiš trenutno i zašto?“

Autor: Dušan Antonijević – saradnik ITNetwork.rs
Hvala na čitanju! Podeli tekst sa kolegama.

Banner

Banner

Možda će vam se svideti i