📡 Μάθημα 12: Web Services, REST APIs & Git

Υπηρεσίες Ιστού, APIs και Συνεργατική Ανάπτυξη

🌐 1. Τι είναι τα Web Services;

Τα Web Services (Υπηρεσίες Ιστού) είναι προγράμματα που τρέχουν σε έναν server και επιτρέπουν σε διαφορετικές εφαρμογές να επικοινωνούν μεταξύ τους μέσω του internet.

🎯 Απλό παράδειγμα:

Σκέψου ότι φτιάχνεις μια εφαρμογή καιρού. Αντί να μαζεύεις εσύ δεδομένα από μετεωρολογικούς σταθμούς, μπορείς να ζητήσεις τα δεδομένα από ένα Weather API (π.χ. OpenWeatherMap).

  • Η εφαρμογή σου στέλνει ένα αίτημα στο API
  • Το API απαντάει με δεδομένα (θερμοκρασία, υγρασία κ.λπ.)
  • Η εφαρμογή σου εμφανίζει τα δεδομένα στον χρήστη

📋 Τι προσφέρουν τα Web Services;

Πλεονέκτημα Περιγραφή
Επαναχρησιμοποίηση Πολλές εφαρμογές μπορούν να χρησιμοποιούν την ίδια υπηρεσία
Ανεξαρτησία Το frontend και το backend μπορούν να αναπτυχθούν ξεχωριστά
Επεκτασιμότητα Εύκολη προσθήκη νέων λειτουργιών
Διαλειτουργικότητα Διαφορετικές γλώσσες/πλατφόρμες μπορούν να συνεργαστούν

🔌 2. Τι είναι το REST API;

Το REST (Representational State Transfer) είναι ένα αρχιτεκτονικό στυλ για τη δημιουργία Web Services. Ένα REST API είναι μια διεπαφή που ακολουθεί τους κανόνες του REST.

💡 Απλή εξήγηση:

Το REST API είναι σαν ένα μενού εστιατορίου:

  • Το μενού σου λέει τι μπορείς να παραγγείλεις (endpoints)
  • Εσύ δίνεις την παραγγελία (request)
  • Η κουζίνα ετοιμάζει το φαγητό (server processing)
  • Ο σερβιτόρος σου φέρνει το πιάτο (response)

📝 Βασικές Αρχές του REST

  1. Client-Server: Ο client (browser/app) και ο server είναι ξεχωριστά
  2. Stateless: Κάθε αίτημα είναι ανεξάρτητο - ο server δεν θυμάται προηγούμενα αιτήματα
  3. Uniform Interface: Χρησιμοποιούμε τυποποιημένες HTTP μεθόδους
  4. Resource-Based: Τα δεδομένα αναπαρίστανται ως "πόροι" (resources)

📬 3. HTTP Methods - Οι Μέθοδοι του REST

Το REST χρησιμοποιεί τις HTTP μεθόδους για να περιγράψει τι θέλουμε να κάνουμε με τα δεδομένα:

Μέθοδος Ενέργεια (CRUD) Περιγραφή Παράδειγμα
GET Read (Ανάγνωση) Παίρνουμε δεδομένα Λίστα χρηστών
POST Create (Δημιουργία) Δημιουργούμε νέα δεδομένα Νέος χρήστης
PUT Update (Ενημέρωση) Ενημερώνουμε υπάρχοντα δεδομένα Αλλαγή email
DELETE Delete (Διαγραφή) Διαγράφουμε δεδομένα Διαγραφή χρήστη
🔤 CRUD = Create, Read, Update, Delete

Αυτές είναι οι 4 βασικές λειτουργίες που κάνουμε σε δεδομένα. Το REST τις αντιστοιχίζει στις HTTP μεθόδους.

🛣️ Παραδείγματα REST Endpoints

Endpoint Μέθοδος Περιγραφή
/api/users GET Λίστα όλων των χρηστών
/api/users/5 GET Στοιχεία του χρήστη με id=5
/api/users POST Δημιουργία νέου χρήστη
/api/users/5 PUT Ενημέρωση χρήστη με id=5
/api/users/5 DELETE Διαγραφή χρήστη με id=5

📦 4. JSON - Η Γλώσσα Επικοινωνίας

Το JSON (JavaScript Object Notation) είναι το πιο δημοφιλές format για ανταλλαγή δεδομένων σε REST APIs. Είναι απλό και εύκολο στην ανάγνωση.

📄 Παράδειγμα JSON

{ "id": 1, "username": "giannis", "email": "[email protected]", "age": 25, "active": true, "roles": ["user", "editor"] }
📋 Κανόνες JSON:
  • Τα κλειδιά είναι πάντα σε εισαγωγικά (διπλά)
  • Τα strings είναι σε διπλά εισαγωγικά
  • Οι αριθμοί χωρίς εισαγωγικά
  • Boolean: true ή false (πεζά)
  • Arrays: [ ]
  • Objects: { }

5. Χρήση External API - OpenWeatherMap

Θα δουλέψουμε με το OpenWeatherMap API για να πάρουμε δεδομένα καιρού.

5.1 Τι είναι το API Key;

Για να καλέσουμε ένα external API, συνήθως χρειαζόμαστε API Key. Είναι σαν μια "ταυτότητα" της εφαρμογής μας.

5.2 Βήματα για απόκτηση API Key

  1. Sign up στο openweathermap.org
  2. Δημιουργία API Key από το μενού "API Keys"
  3. Κρατάμε το key (π.χ. abcd1234)

5.3 Το Endpoint που θα χρησιμοποιήσουμε

GET https://api.openweathermap.org/data/2.5/weather

Documentation: https://openweathermap.org/api/one-call-api

Υποχρεωτικά parameters:

Param Τι είναι
q Όνομα πόλης (π.χ. Athens, Tripoli)
appid API key

Προαιρετικά (αλλά πολύ χρήσιμα):

Param Τι κάνει
units metric (Celsius)
lang el (ελληνικά)

5.4 Παράδειγμα με πραγματικές τιμές (Αθήνα)

https://api.openweathermap.org/data/2.5/weather?q=Athens&units=metric&lang=el&appid=API_KEY

5.5 Πρώτο request με curl

Το curl είναι ένα εργαλείο γραμμής εντολών για αποστολή HTTP requests. Είναι ιδανικό για να τεστάρουμε APIs γρήγορα.

curl "https://api.openweathermap.org/data/2.5/weather?q=Athens&units=metric&lang=el&appid=YOUR_API_KEY"

Αποτέλεσμα (raw - χωρίς μορφοποίηση):

{"coord":{"lon":23.7162,"lat":37.9795},"weather":[{"id":801,"main":"Clouds","description":"ελαφρές νεφώσεις","icon":"02d"}],"base":"stations","main":{"temp":18.03,"feels_like":17.72,"temp_min":17.21,"temp_max":19.03,"pressure":1019,"humidity":70},"visibility":10000,"wind":{"speed":5.81,"deg":163},"clouds":{"all":20},"sys":{"country":"GR","sunrise":1767505281,"sunset":1767539894},"timezone":7200,"name":"Αθήνα","cod":200}

Δύσκολο να διαβαστεί! Ας το κάνουμε όμορφο με την εντολή jq:

curl "https://api.openweathermap.org/data/2.5/weather?q=Athens&units=metric&lang=el&appid=YOUR_API_KEY" | jq

Αποτέλεσμα (όπως βγαίνει από το terminal):

{ "coord": { "lon": 23.7162, "lat": 37.9795 }, "weather": [ { "id": 801, "main": "Clouds", "description": "ελαφρές νεφώσεις", "icon": "02d" } ], "main": { "temp": 18.03, "feels_like": 17.72, "temp_min": 17.21, "temp_max": 19.03, "pressure": 1019, "humidity": 70 }, "visibility": 10000, "wind": { "speed": 5.81, "deg": 163 }, "name": "Αθήνα", "cod": 200 }

Επεξήγηση πεδίων:

{ "coord": { "lon": 23.7162, // Γεωγραφικό μήκος "lat": 37.9795 // Γεωγραφικό πλάτος }, "weather": [ { "id": 801, // Κωδικός καιρού "main": "Clouds", // Κατηγορία καιρού "description": "ελαφρές νεφώσεις", // Περιγραφή (στα ελληνικά λόγω lang=el) "icon": "02d" // Εικονίδιο καιρού } ], "main": { "temp": 18.03, // Τρέχουσα θερμοκρασία (°C λόγω units=metric) "feels_like": 17.72, // Αίσθηση θερμοκρασίας "temp_min": 17.21, // Ελάχιστη θερμοκρασία "temp_max": 19.03, // Μέγιστη θερμοκρασία "pressure": 1019, // Ατμοσφαιρική πίεση (hPa) "humidity": 70 // Υγρασία (%) }, "visibility": 10000, // Ορατότητα (μέτρα) "wind": { "speed": 5.81, // Ταχύτητα ανέμου (m/s) "deg": 163 // Κατεύθυνση ανέμου (μοίρες) }, "name": "Αθήνα", // Όνομα πόλης "cod": 200 // HTTP status code (200 = επιτυχία) }
Επεξήγηση εικονιδίου:

Το πεδίο "icon": "02d" μας δίνει τον κωδικό του εικονιδίου. Μπορούμε να το εμφανίσουμε με το URL:

https://openweathermap.org/img/wn/[email protected]

Weather icon

Τι είναι το jq;

Το jq είναι εργαλείο για επεξεργασία JSON στο terminal. Εγκατάσταση:

  • Mac: brew install jq
  • Linux: sudo apt install jq
  • Windows: choco install jq

5.6 Κλήση με Postman

Το Postman είναι ένα γραφικό εργαλείο για testing APIs. Πιο εύκολο από το curl για αρχάριους.

Βήματα:

  1. Κατέβασε το Postman από postman.com/downloads
  2. Δημιούργησε νέο GET request
  3. Βάλε το URL: https://api.openweathermap.org/data/2.5/weather
  4. Στο tab Params πρόσθεσε:
Key Value
q Athens
units metric
lang el
appid YOUR_API_KEY

Πάτα Send και θα δεις το JSON response με όμορφη μορφοποίηση!

Postman Screenshot

Πλεονεκτήματα Postman:
  • Αυτόματη μορφοποίηση JSON
  • Αποθήκευση requests για μελλοντική χρήση
  • Εύκολη διαχείριση headers και parameters
  • History όλων των κλήσεων

5.7 Παράδειγμα: SMS API

Ας δούμε ένα διαφορετικό API που χρησιμοποιεί POST αντί για GET και διαφορετικό τρόπο authentication.

Base URL: https://services.yuboto.com/omni/v1

Send endpoint: https://services.yuboto.com/omni/v1/Send

Στοιχείο Τιμή
Method POST
Content-Type application/json; charset=utf-8
Authorization Basic <base64(API_KEY)>
Τι αλλάζει εδώ σε σχέση με πριν;

Στο OpenWeather είχαμε:

?appid=API_KEY

API key ως query parameter

Στο SMS API της Yuboto έχουμε:

Authorization: Basic <base64(...)>

API key μέσα σε HTTP header, κωδικοποιημένο με Base64

Τι είναι τελικά αυτό το Base64;

Σημαντικό:
  • Το Base64 ΔΕΝ είναι encryption
  • ΔΕΝ δημιουργεί νέο κλειδί
  • ΔΕΝ αλλάζει το API key σου

Είναι απλή μετατροπή μορφής (encoding).

Παράδειγμα:

Αν το API key σου είναι:

my-secret-api-key

Όταν κάνεις:

echo -n "my-secret-api-key" | base64

Παίρνεις:

bXktc2VjcmV0LWFwaS1rZXk=

Αυτό ΔΕΝ είναι νέο secret. Είναι ο ίδιος ακριβώς χαρακτήρας, απλώς σε μορφή που επιτρέπεται σε HTTP headers.

Γιατί ζητάνε Base64 και όχι σκέτο το key;

Γιατί χρησιμοποιούν HTTP Basic Authentication. Το πρότυπο λέει:

Authorization: Basic <base64(credentials)>

Συνήθως τα credentials είναι username:password. Στην περίπτωση της Yuboto:

Είναι design επιλογή του API.

Άρα τι στέλνεται πραγματικά στο request;

Αν γράφεις:

Authorization: Basic bXktc2VjcmV0LWFwaS1rZXk=

Ο server:

  1. Κάνει base64 decode
  2. Παίρνει πίσω: my-secret-api-key
  3. Το συγκρίνει με τη βάση του
  4. Αν ταιριάζει → OK

5.8 Κλήση SMS API με curl

curl -X POST "https://services.yuboto.com/omni/v1/Send" \ -H "Content-Type: application/json; charset=utf-8" \ -H "Authorization: Basic YOUR_BASE64_API_KEY" \ -d '{ "dlr": "false", "callbackUrl": null, "option1": null, "option2": null, "contacts": [ { "phonenumber": "3069XXXXXXXX" } ], "dateinToSend": null, "timeinToSend": null, "sms": { "sender": "TestSMS", "text": "Test SMS από curl", "validity": 180, "typesms": "sms", "longsms": "false", "priority": 1 } }'

Αναλυτική επεξήγηση κάθε γραμμής:

# POST request στο Yuboto API για αποστολή SMS curl -X POST "https://services.yuboto.com/omni/v1/Send" \ # Δηλώνουμε ότι στέλνουμε JSON (UTF-8 για ελληνικά) -H "Content-Type: application/json; charset=utf-8" \ # Authentication: Base64 API key (αλλιώς 401 error) -H "Authorization: Basic YOUR_BASE64_API_KEY" \ # Αρχή JSON body (τα δεδομένα του request) -d '{ # Delivery report: false = δεν θέλουμε report παράδοσης "dlr": "false", # URL callback για DLR (null = δεν χρησιμοποιείται) "callbackUrl": null, # Προαιρετικά custom fields (δεν χρησιμοποιούνται) "option1": null, "option2": null, # Λίστα παραληπτών SMS "contacts": [ # Τηλέφωνο σε διεθνή μορφή (30 = Ελλάδα) { "phonenumber": "3069XXXXXXXX" } ], # Ημερομηνία αποστολής (null = άμεση αποστολή) "dateinToSend": null, # Ώρα αποστολής (null = άμεση αποστολή) "timeinToSend": null, # Ρυθμίσεις του SMS "sms": { # Αποστολέας (πρέπει να είναι εγκεκριμένος) "sender": "TestSMS", # Το κείμενο του SMS (υποστηρίζει ελληνικά) "text": "Test SMS από curl", # Χρόνος ισχύος SMS σε λεπτά "validity": 180, # Τύπος μηνύματος (sms) "typesms": "sms", # false = απλό SMS, true = multipart SMS "longsms": "false", # Προτεραιότητα αποστολής (1 = κανονική) "priority": 1 } }' # Τέλος JSON body

Διαφορές από το Weather API:

5.9 Αποστολή SMS με Postman

1. Δημιούργησε νέο Request

2. Authorization tab (Προσοχή!)

ΔΕΝ χρησιμοποιούμε το Authorization tab του Postman!

Ο λόγος: Το Yuboto δεν θέλει Postman-style auth, θέλει χειροκίνητο header.

3. Headers tab (ΕΔΩ είναι το auth)

Πρόσθεσε ακριβώς αυτά τα 2 headers:

Key Value
Content-Type application/json; charset=utf-8
Authorization Basic YOUR_BASE64_API_KEY
Προσοχή: Ολόκληρο το value πρέπει να είναι Basic ... (με το "Basic " μπροστά)

4. Body tab

Κάνε paste αυτό:

{ "dlr": "false", "callbackUrl": null, "option1": null, "option2": null, "contacts": [ { "phonenumber": "3069XXXXXXXX" } ], "dateinToSend": null, "timeinToSend": null, "sms": { "sender": "TestSMS", "text": "Test SMS από Postman", "validity": 180, "typesms": "sms", "longsms": "false", "priority": 1 } }

5. Πάτα Send

Αναμενόμενο αποτέλεσμα:

{ "ErrorCode": 0, "ErrorMessage": null, "Message": [ { "id": "...", "channel": "omni", "phonenumber": "3069XXXXXXXX", "status": "submitted", "errorCode": 0 } ] }

5.10 Θεωρία: PHP συναρτήσεις για API

file_get_contents()

Τι είναι: Συνάρτηση της PHP που διαβάζει περιεχόμενο από ένα αρχείο ή URL.

Πώς δουλεύει:

file_get_contents("https://example.com");

Η PHP:

Στην περίπτωσή μας:

$json = file_get_contents($url);

Το $json είναι απλό κείμενο, όχι δεδομένα PHP.

json_decode()

Τι κάνει: Μετατρέπει JSON string → PHP μεταβλητή.

Σύνταξη:

json_decode($json, true);

Χωρίς true → object (πιο δύσκολο για αρχή).

Γιατί τα κάνουμε αυτά;

Βήμα Τι έχουμε
API response JSON string
json_decode μεταφραστής
PHP arrays

5.11 Κώδικας PHP (weather.php)

<?php // API key (προσωρινά hardcoded) $apiKey = 'ΤΟ_API_KEY_ΣΟΥ_ΕΔΩ'; // Σταθερή πόλη (για απλότητα) $city = 'Athens'; // Δημιουργούμε το URL του API $url = "https://api.openweathermap.org/data/2.5/weather?q=$city&units=metric&lang=el&appid=$apiKey"; // 1. Καλούμε το API και παίρνουμε JSON (string) $json = file_get_contents($url); // 2. Μετατρέπουμε JSON → PHP array $data = json_decode($json, true); // 3. Χρησιμοποιούμε τα δεδομένα echo "Πόλη: {$data['name']}<br>"; echo "Θερμοκρασία: {$data['main']['temp']} °C<br>"; echo "Καιρός: {$data['weather'][0]['description']}<br>"; ?>

6. Git - Συνεργατική Ανάπτυξη

Το Git είναι ένα σύστημα ελέγχου εκδόσεων (version control) που μας επιτρέπει να παρακολουθούμε αλλαγές στον κώδικα και να συνεργαζόμαστε με άλλους προγραμματιστές.

Γιατί χρειαζόμαστε το Git;
  • Ιστορικό αλλαγών: Μπορούμε να δούμε ποιος άλλαξε τι και πότε
  • Backup: Ο κώδικας αποθηκεύεται σε απομακρυσμένο server
  • Συνεργασία: Πολλοί προγραμματιστές μπορούν να δουλεύουν ταυτόχρονα
  • Rollback: Μπορούμε να γυρίσουμε πίσω σε προηγούμενη έκδοση

11.1 Εγκατάσταση Git

# Windows: Κατεβάστε από https://git-scm.com # Linux (Ubuntu/Debian): sudo apt install git # macOS: brew install git # Έλεγχος εγκατάστασης: git --version

11.2 Αρχική Ρύθμιση

# Ορίζουμε το όνομα και email μας (εμφανίζονται στα commits) git config --global user.name "Γιάννης Παπαδόπουλος" git config --global user.email "[email protected]" # Έλεγχος ρυθμίσεων: git config --list

11.3 Βασικές Εντολές Git

Εντολή Περιγραφή
git init Δημιουργία νέου repository
git clone <url> Κλωνοποίηση υπάρχοντος repository
git status Εμφάνιση κατάστασης αρχείων
git add <file> Προσθήκη αρχείου στο staging
git add . Προσθήκη ΟΛΩΝ των αρχείων
git commit -m "msg" Αποθήκευση αλλαγών
git push Αποστολή στον server
git pull Λήψη από τον server
git log Ιστορικό commits

11.4 Πρακτικό Παράδειγμα

# ΒΗΜΑ 1: Δημιουργία νέου project mkdir my-api-project cd my-api-project # ΒΗΜΑ 2: Αρχικοποίηση Git repository git init # Δημιουργεί τον φάκελο .git # ΒΗΜΑ 3: Δημιουργία αρχείων (config.php, users.php κ.λπ.) # ... γράφουμε τον κώδικα ... # ΒΗΜΑ 4: Έλεγχος κατάστασης git status # Θα δείξει τα untracked files (κόκκινα) # ΒΗΜΑ 5: Προσθήκη αρχείων στο staging area git add . # Τώρα τα αρχεία είναι "staged" (πράσινα) # ΒΗΜΑ 6: Commit - Αποθήκευση στο ιστορικό git commit -m "Initial commit: REST API for users" # ΒΗΜΑ 7: Σύνδεση με GitHub (αφού δημιουργήσουμε repo) git remote add origin https://github.com/username/my-api-project.git # ΒΗΜΑ 8: Push στο GitHub git push -u origin main

11.5 Branches - Κλαδιά

Τα branches μας επιτρέπουν να εργαζόμαστε σε νέες λειτουργίες χωρίς να επηρεάζουμε τον κύριο κώδικα.

# Δημιουργία νέου branch git branch feature-login # Μετάβαση σε branch git checkout feature-login # Ή και τα δύο μαζί: git checkout -b feature-login # Εμφάνιση όλων των branches git branch # Επιστροφή στο main git checkout main # Συγχώνευση branch στο main git merge feature-login # Διαγραφή branch (μετά τη συγχώνευση) git branch -d feature-login

Οπτικοποίηση Branches

main:           ●───●───●───●───●───●
                     \         /
feature-login:        ●───●───●
                

11.6 Συνεργασία με Pull Requests

Όταν εργαζόμαστε σε ομάδα με GitHub/GitLab:

  1. Clone: Κάθε μέλος κλωνοποιεί το repository
  2. Branch: Δημιουργεί δικό του branch για τη δουλειά του
  3. Commit + Push: Ανεβάζει τις αλλαγές του
  4. Pull Request: Ζητάει review από την ομάδα
  5. Merge: Αφού εγκριθεί, συγχωνεύεται στο main
Καλές Πρακτικές:
  • Κάνε git pull πριν ξεκινήσεις να δουλεύεις
  • Γράψε περιγραφικά commit messages
  • Κάνε μικρά, συχνά commits
  • Δημιούργησε .gitignore για αρχεία που δεν πρέπει να ανέβουν

11.7 Αρχείο .gitignore

Το αρχείο .gitignore λέει στο Git ποια αρχεία να αγνοήσει:

# Αρχεία ρυθμίσεων με passwords config.php .env # Φάκελοι dependencies vendor/ node_modules/ # Αρχεία IDE .idea/ .vscode/ # Logs *.log # Προσωρινά αρχεία *.tmp *.swp

7. Ανακεφαλαίωση

Τι μάθαμε σήμερα:
  • Web Services: Υπηρεσίες που επιτρέπουν επικοινωνία μεταξύ εφαρμογών
  • REST API: Αρχιτεκτονικό στυλ με HTTP μεθόδους (GET, POST, PUT, DELETE)
  • JSON: Το format ανταλλαγής δεδομένων
  • External APIs: Χρήση εξωτερικών υπηρεσιών (π.χ. OpenWeatherMap) με API Key
  • Front-end/Back-end: Ανεξάρτητη ανάπτυξη με επικοινωνία μέσω API
  • Fetch API: JavaScript για κλήση REST APIs
  • Git: Έλεγχος εκδόσεων και συνεργατική ανάπτυξη
Χρήσιμοι Σύνδεσμοι:

Τέλος Μαθήματος 12

Web Services, REST APIs & Git