Tam Çalışan Örnek Projeler ve Genel Anlatım (C#, MVC, Java, Python, PHP, React, MATLAB, C++)
Bu bölümde, aynı problem tanımını farklı teknolojilerle çözebileceğin tam çalışan örnek proje önerileri ve her biri için kısa mimari rehber bulacaksın. Amaç: portföyünde üretim-yakın (deploy edilebilir) projeler biriktirmek.
1) C# • ASP.NET Core 8 Minimal API + EF Core (SQLite)
Dosya yapısı (öneri)
Lms.CSharp/
Lms.CSharp.csproj
Program.cs
Models.cs
Lms.CSharp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6" />
</ItemGroup>
</Project>
Models.cs
using Microsoft.EntityFrameworkCore;
public class Course { public int Id { get; set; } public string Title { get; set; } = ""; }
public class Student { public int Id { get; set; } public string Name { get; set; } = ""; public string Email { get; set; } = ""; }
public class Enrolment
{
public int Id { get; set; }
public int StudentId { get; set; }
public int CourseId { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public Student? Student { get; set; }
public Course? Course { get; set; }
}
public class LmsDb : DbContext
{
public LmsDb(DbContextOptions<LmsDb> opts) : base(opts) { }
public DbSet<Course> Courses => Set<Course>();
public DbSet<Student> Students => Set<Student>();
public DbSet<Enrolment> Enrolments => Set<Enrolment>();
protected override void OnModelCreating(ModelBuilder b)
{
b.Entity<Student>().HasIndex(x => x.Email).IsUnique();
b.Entity<Enrolment>()
.HasOne(e => e.Student).WithMany().HasForeignKey(e => e.StudentId).OnDelete(DeleteBehavior.Cascade);
b.Entity<Enrolment>()
.HasOne(e => e.Course).WithMany().HasForeignKey(e => e.CourseId).OnDelete(DeleteBehavior.Cascade);
}
}
Program.cs
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<LmsDb>(o => o.UseSqlite("Data Source=lms.db"));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<LmsDb>();
db.Database.EnsureCreated();
}
app.UseCors();
// Courses
app.MapGet("/courses", async (LmsDb db) => await db.Courses.ToListAsync());
app.MapPost("/courses", async (LmsDb db, Course c) => { db.Courses.Add(c); await db.SaveChangesAsync(); return Results.Created($"/courses/{c.Id}", c); });
// Students
app.MapGet("/students", async (LmsDb db) => await db.Students.ToListAsync());
app.MapPost("/students", async (LmsDb db, Student s) => { db.Students.Add(s); await db.SaveChangesAsync(); return Results.Created($"/students/{s.Id}", s); });
// Enrolments (list with joins)
app.MapGet("/enrolments", async (LmsDb db) =>
await db.Enrolments.Include(e=>e.Student).Include(e=>e.Course)
.Select(e => new { e.Id, e.CreatedAt, student = e.Student!.Name, course = e.Course!.Title })
.ToListAsync());
app.MapPost("/enrolments", async (LmsDb db, Enrolment e) =>
{
if (!await db.Students.AnyAsync(s => s.Id == e.StudentId) || !await db.Courses.AnyAsync(c => c.Id == e.CourseId))
return Results.BadRequest(new { error = "invalid ids" });
db.Enrolments.Add(e); await db.SaveChangesAsync(); return Results.Created($"/enrolments/{e.Id}", e);
});
app.Run();
Çalıştırma
dotnet new web -n Lms.CSharp
# dosyaları üzerine yaz
dotnet restore
dotnet run
# http://localhost:5000/courses vb.
2) Java • Spring Boot 3 + Spring Data JPA (H2)
Dosya yapısı
lms-java/
pom.xml
src/main/java/com/example/lms/LmsApplication.java
src/main/java/com/example/lms/model/{Course.java,Student.java,Enrolment.java}
src/main/java/com/example/lms/repo/{CourseRepo.java,StudentRepo.java,EnrolRepo.java}
src/main/java/com/example/lms/web/{CourseController.java,StudentController.java,EnrolController.java}
src/main/resources/application.properties
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId><artifactId>lms</artifactId><version>0.0.1</version>
<properties><java.version>17</java.version><spring.boot.version>3.3.1</spring.boot.version></properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version><type>pom</type><scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency>
</dependencies>
<build><plugins><plugin>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
</plugin></plugins></build>
</project>
application.properties
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:lms;DB_CLOSE_DELAY=-1;MODE=PostgreSQL
spring.jpa.hibernate.ddl-auto=update
Model’ler (özet)
Course.java
package com.example.lms.model;
import jakarta.persistence.*; @Entity
public class Course { @Id @GeneratedValue private Integer id; private String title;
public Integer getId(){return id;} public void setId(Integer id){this.id=id;}
public String getTitle(){return title;} public void setTitle(String t){this.title=t;}
}
Student.java
package com.example.lms.model;
import jakarta.persistence.*; @Entity
public class Student { @Id @GeneratedValue private Integer id; private String name; @Column(unique=true) private String email;
public Integer getId(){return id;} public void setId(Integer id){this.id=id;}
public String getName(){return name;} public void setName(String v){name=v;}
public String getEmail(){return email;} public void setEmail(String e){email=e;}
}
Enrolment.java
package com.example.lms.model;
import jakarta.persistence.*; import java.time.*;
@Entity
public class Enrolment { @Id @GeneratedValue private Integer id;
@ManyToOne(optional=false) private Student student;
@ManyToOne(optional=false) private Course course;
private LocalDateTime createdAt = LocalDateTime.now();
public Integer getId(){return id;} public Student getStudent(){return student;} public Course getCourse(){return course;}
public void setStudent(Student s){student=s;} public void setCourse(Course c){course=c;}
public LocalDateTime getCreatedAt(){return createdAt;} public void setCreatedAt(LocalDateTime d){createdAt=d;}
}
Repo’lar
package com.example.lms.repo;
import com.example.lms.model.*; import org.springframework.data.jpa.repository.JpaRepository;
public interface CourseRepo extends JpaRepository<Course,Integer>{}
public interface StudentRepo extends JpaRepository<Student,Integer>{}
public interface EnrolRepo extends JpaRepository<Enrolment,Integer>{}
Controller’lar (özet)
CourseController.java
package com.example.lms.web;
import com.example.lms.model.*; import com.example.lms.repo.*; import org.springframework.web.bind.annotation.*;
import java.util.*; @RestController
public class CourseController {
private final CourseRepo repo; public CourseController(CourseRepo r){this.repo=r;}
@GetMapping("/courses") public List<Course> all(){ return repo.findAll(); }
@PostMapping("/courses") public Course add(@RequestBody Course c){ return repo.save(c); }
}
StudentController.java
package com.example.lms.web;
import com.example.lms.model.*; import com.example.lms.repo.*; import org.springframework.web.bind.annotation.*; import java.util.*;
@RestController
public class StudentController {
private final StudentRepo repo; public StudentController(StudentRepo r){repo=r;}
@GetMapping("/students") public List<Student> all(){ return repo.findAll(); }
@PostMapping("/students") public Student add(@RequestBody Student s){ return repo.save(s); }
}
EnrolController.java
package com.example.lms.web;
import com.example.lms.model.*; import com.example.lms.repo.*; import org.springframework.web.bind.annotation.*;
import java.util.*; @RestController
public class EnrolController {
private final EnrolRepo er; private final StudentRepo sr; private final CourseRepo cr;
public EnrolController(EnrolRepo e, StudentRepo s, CourseRepo c){er=e; sr=s; cr=c;}
@GetMapping("/enrolments") public List<Map<String,Object>> list(){
List<Map<String,Object>> out = new ArrayList<>();
for (var e : er.findAll()){
out.add(Map.of("id",e.getId(),"createdAt",e.getCreatedAt(),
"student",e.getStudent().getName(),"course",e.getCourse().getTitle()));
} return out;
}
@PostMapping("/enrolments") public Object add(@RequestBody Map<String,Integer> p){
var s = sr.findById(p.get("student_id")); var c = cr.findById(p.get("course_id"));
if(s.isEmpty()||c.isEmpty()) return Map.of("error","invalid ids");
var e = new Enrolment(); e.setStudent(s.get()); e.setCourse(c.get()); return er.save(e);
}
}
LmsApplication.java
package com.example.lms;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class LmsApplication { public static void main(String[] args){ SpringApplication.run(LmsApplication.class,args); } }
Çalıştırma
mvn spring-boot:run
# http://localhost:8080/courses
3) Python • FastAPI + SQLModel (SQLite)
main.py
from fastapi import FastAPI, HTTPException
from sqlmodel import SQLModel, Field, Session, create_engine, select, Relationship
from datetime import datetime
class Course(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True); title: str
class Student(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True); name: str; email: str
class Enrolment(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
student_id: int = Field(foreign_key="student.id")
course_id: int = Field(foreign_key="course.id")
created_at: datetime = Field(default_factory=datetime.utcnow)
engine = create_engine("sqlite:///lms_py.db", echo=False)
SQLModel.metadata.create_all(engine)
app = FastAPI()
@app.get("/courses")
def courses():
with Session(engine) as s: return s.exec(select(Course)).all()
@app.post("/courses")
def add_course(c: Course):
with Session(engine) as s: s.add(c); s.commit(); s.refresh(c); return c
@app.get("/students")
def students():
with Session(engine) as s: return s.exec(select(Student)).all()
@app.post("/students")
def add_student(st: Student):
with Session(engine) as s: s.add(st); s.commit(); s.refresh(st); return st
@app.get("/enrolments")
def enrolments():
with Session(engine) as s:
q = """
SELECT e.id, e.created_at, st.name as student, c.title as course
FROM enrolment e JOIN student st ON st.id=e.student_id JOIN course c ON c.id=e.course_id
"""
return [dict(r) for r in s.exec(q)]
@app.post("/enrolments")
def add_enrol(e: Enrolment):
with Session(engine) as s:
if not s.get(Student, e.student_id) or not s.get(Course, e.course_id):
raise HTTPException(400, "invalid ids")
s.add(e); s.commit(); s.refresh(e); return e
Çalıştırma
pip install fastapi uvicorn sqlmodel
uvicorn main:app --reload
# http://127.0.0.1:8000/courses
4) PHP • Slim 4 + PDO (SQLite)
composer.json
{
"require": {
"slim/slim": "^4.12",
"slim/psr7": "^1.6"
},
"autoload": { "psr-4": { "App\\": "src/" } }
}
public/index.php
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->addBodyParsingMiddleware();
$db = new PDO('sqlite:' . __DIR__ . '/../lms_php.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("CREATE TABLE IF NOT EXISTS course(id INTEGER PRIMARY KEY, title TEXT);
CREATE TABLE IF NOT EXISTS student(id INTEGER PRIMARY KEY, name TEXT, email TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS enrolment(id INTEGER PRIMARY KEY, student_id INT, course_id INT, created_at TEXT DEFAULT (datetime('now')));");
/* Courses */
$app->get('/courses', function(Request $r, Response $resp) use($db){
$rows = $db->query("SELECT * FROM course")->fetchAll(PDO::FETCH_ASSOC);
$resp->getBody()->write(json_encode($rows)); return $resp->withHeader('Content-Type','application/json');
});
$app->post('/courses', function(Request $r, Response $resp) use($db){
$data = $r->getParsedBody(); $stmt=$db->prepare("INSERT INTO course(title) VALUES(?)"); $stmt->execute([$data['title']??'']);
$id = $db->lastInsertId(); $resp->getBody()->write(json_encode(['id'=>$id,'title'=>$data['title']])); return $resp->withHeader('Content-Type','application/json');
});
/* Students */
$app->get('/students', function(Request $r, Response $resp) use($db){
$rows = $db->query("SELECT * FROM student")->fetchAll(PDO::FETCH_ASSOC);
$resp->getBody()->write(json_encode($rows)); return $resp->withHeader('Content-Type','application/json');
});
$app->post('/students', function(Request $r, Response $resp) use($db){
$data = $r->getParsedBody(); $stmt=$db->prepare("INSERT INTO student(name,email) VALUES(?,?)"); $stmt->execute([$data['name']??'', $data['email']??'']);
$id = $db->lastInsertId(); $resp->getBody()->write(json_encode(['id'=>$id,'name'=>$data['name'],'email'=>$data['email']])); return $resp->withHeader('Content-Type','application/json');
});
/* Enrolments */
$app->get('/enrolments', function(Request $r, Response $resp) use($db){
$rows = $db->query("SELECT e.id, e.created_at, s.name as student, c.title as course
FROM enrolment e JOIN student s ON s.id=e.student_id JOIN course c ON c.id=e.course_id")->fetchAll(PDO::FETCH_ASSOC);
$resp->getBody()->write(json_encode($rows)); return $resp->withHeader('Content-Type','application/json');
});
$app->post('/enrolments', function(Request $r, Response $resp) use($db){
$d = $r->getParsedBody();
$okS = $db->query("SELECT 1 FROM student WHERE id=".(int)$d['student_id'])->fetch();
$okC = $db->query("SELECT 1 FROM course WHERE id=".(int)$d['course_id'])->fetch();
if(!$okS || !$okC){ $resp->getBody()->write(json_encode(['error'=>'invalid ids'])); return $resp->withStatus(400)->withHeader('Content-Type','application/json'); }
$stmt = $db->prepare("INSERT INTO enrolment(student_id,course_id) VALUES(?,?)"); $stmt->execute([(int)$d['student_id'], (int)$d['course_id']]);
$resp->getBody()->write(json_encode(['id'=>$db->lastInsertId()])); return $resp->withHeader('Content-Type','application/json');
});
$app->run();
Çalıştırma
composer install
php -S localhost:8085 -t public
# http://localhost:8085/courses
5) React • Vite (API’yi tüketen basit panel)
src/App.jsx
import { useEffect, useState } from "react";
const API = import.meta.env.VITE_API || "http://localhost:5000"; // C# varsayılan
export default function App(){
const [courses,setCourses]=useState([]); const [students,setStudents]=useState([]); const [enr,setEnr]=useState([]);
useEffect(()=>{
Promise.all([
fetch(`${API}/courses`).then(r=>r.json()),
fetch(`${API}/students`).then(r=>r.json()),
fetch(`${API}/enrolments`).then(r=>r.json())
]).then(([c,s,e])=>{setCourses(c);setStudents(s);setEnr(e);});
},[]);
const createCourse = async (title) => {
await fetch(`${API}/courses`, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({title})});
setCourses(await (await fetch(`${API}/courses`)).json());
};
return (
<div style={{padding:24,fontFamily:"Inter, system-ui"}}>
<h1>Limit LMS (React demo)</h1>
<section>
<h2>Kurslar</h2>
<button onClick={()=>createCourse(prompt("Kurs adı?")||"Yeni Kurs")}>+ Kurs Ekle</button>
<ul>{courses.map(c=><li key={c.id}>{c.title}</li>)}</ul>
</section>
<section>
<h2>Öğrenciler</h2>
<ul>{students.map(s=><li key={s.id}>{s.name} ({s.email})</li>)}</ul>
</section>
<section>
<h2>Kayıtlar</h2>
<ul>{enr.map(e=><li key={e.id}>{e.student} → {e.course} <small>{new Date(e.createdAt).toLocaleString()}</small></li>)}</ul>
</section>
</div>
);
}
Çalıştırma
npm create vite@latest lms-react -- --template react
cd lms-react && npm i && npm i
# .env dosyasına VITE_API=http://localhost:5000 gibi yaz
npm run dev
6) MATLAB • REST + Basit Analitik
lms_analytics.m
base = 'http://localhost:5000'; % C# api
opts = weboptions('Timeout', 20);
courses = webread([base '/courses'], opts);
students = webread([base '/students'], opts);
enrols = webread([base '/enrolments'], opts);
disp('Toplam kurs sayısı:'); disp(numel(courses));
disp('Toplam öğrenci sayısı:'); disp(numel(students));
disp('Kayıt dağılımı (kurs bazlı):');
keys = {enrols.course}; [u,~,idx] = unique(keys); counts = accumarray(idx,1);
T = table(u', counts, 'VariableNames', {'Kurs','Kayit'}); disp(T);
bar(counts); set(gca,'XTickLabel',u); title('Kurs Bazlı Kayıt'); xlabel('Kurs'); ylabel('Kayıt');
7) C++ • SQLite tabanlı küçük REST sunucusu (cpp-httplib ile)
Not: Tek header
httplib.h(https://github.com/yhirose/cpp-httplib) ve-lsqlite3gerekir.
server.cpp
#include "httplib.h"
#include <sqlite3.h>
#include <nlohmann/json.hpp> // https://github.com/nlohmann/json
using json = nlohmann::json;
static sqlite3* db;
int main(){
if(sqlite3_open("lms_cpp.db",&db)!=SQLITE_OK) return 1;
const char* ddl =
"CREATE TABLE IF NOT EXISTS course(id INTEGER PRIMARY KEY, title TEXT);"
"CREATE TABLE IF NOT EXISTS student(id INTEGER PRIMARY KEY, name TEXT, email TEXT UNIQUE);"
"CREATE TABLE IF NOT EXISTS enrolment(id INTEGER PRIMARY KEY, student_id INT, course_id INT, created_at TEXT DEFAULT CURRENT_TIMESTAMP);";
char* err=nullptr; sqlite3_exec(db, ddl, 0, 0, &err);
httplib::Server srv;
srv.Get("/courses",[](const httplib::Request&, httplib::Response& res){
sqlite3_stmt* st; sqlite3_prepare_v2(db,"SELECT id,title FROM course", -1, &st, 0);
json a=json::array(); while(sqlite3_step(st)==SQLITE_ROW){ a.push_back({{"id",sqlite3_column_int(st,0)},{"title",(const char*)sqlite3_column_text(st,1)}}); }
sqlite3_finalize(st); res.set_content(a.dump(), "application/json");
});
srv.Post("/courses",[](const httplib::Request& req, httplib::Response& res){
auto j=json::parse(req.body); sqlite3_stmt* st; sqlite3_prepare_v2(db,"INSERT INTO course(title) VALUES(?)",-1,&st,0);
sqlite3_bind_text(st,1,j["title"].get<std::string>().c_str(),-1,SQLITE_TRANSIENT); sqlite3_step(st); sqlite3_finalize(st);
res.set_content(j.dump(),"application/json");
});
srv.Get("/students",[](const httplib::Request&, httplib::Response& res){
sqlite3_stmt* st; sqlite3_prepare_v2(db,"SELECT id,name,email FROM student",-1,&st,0);
json a=json::array(); while(sqlite3_step(st)==SQLITE_ROW){
a.push_back({{"id",sqlite3_column_int(st,0)},{"name",(const char*)sqlite3_column_text(st,1)},{"email",(const char*)sqlite3_column_text(st,2)}});
} sqlite3_finalize(st); res.set_content(a.dump(),"application/json");
});
srv.Post("/students",[](const httplib::Request& req, httplib::Response& res){
auto j=json::parse(req.body); sqlite3_stmt* st; sqlite3_prepare_v2(db,"INSERT INTO student(name,email) VALUES(?,?)",-1,&st,0);
sqlite3_bind_text(st,1,j["name"].get<std::string>().c_str(),-1,SQLITE_TRANSIENT);
sqlite3_bind_text(st,2,j["email"].get<std::string>().c_str(),-1,SQLITE_TRANSIENT);
sqlite3_step(st); sqlite3_finalize(st); res.set_content(j.dump(),"application/json");
});
srv.Get("/enrolments",[](const httplib::Request&, httplib::Response& res){
const char* q="SELECT e.id, e.created_at, s.name, c.title FROM enrolment e JOIN student s ON s.id=e.student_id JOIN course c ON c.id=e.course_id";
sqlite3_stmt* st; sqlite3_prepare_v2(db,q,-1,&st,0); json a=json::array();
while(sqlite3_step(st)==SQLITE_ROW){
a.push_back({{"id",sqlite3_column_int(st,0)},{"createdAt",(const char*)sqlite3_column_text(st,1)},
{"student",(const char*)sqlite3_column_text(st,2)},{"course",(const char*)sqlite3_column_text(st,3)}});
} sqlite3_finalize(st); res.set_content(a.dump(),"application/json");
});
srv.Post("/enrolments",[](const httplib::Request& req, httplib::Response& res){
auto j=json::parse(req.body);
sqlite3_stmt* st; sqlite3_prepare_v2(db,"INSERT INTO enrolment(student_id,course_id) VALUES(?,?)",-1,&st,0);
sqlite3_bind_int(st,1,j["student_id"].get<int>()); sqlite3_bind_int(st,2,j["course_id"].get<int>());
sqlite3_step(st); sqlite3_finalize(st); res.set_content(j.dump(),"application/json");
});
printf("C++ server : http://localhost:7000\n");
srv.listen("0.0.0.0",7000);
sqlite3_close(db);
}
Derleme (Linux/macOS örnek)
g++ server.cpp -o lms_cpp -std=c++20 -lsqlite3
./lms_cpp
Tek header bağımlılıkları:
httplib.hvenlohmann/json.hpp’u proje klasörü