Skip to content

บทที่ 0 — ASP.NET Core คืออะไร และทำงานยังไง

สารบัญ .NET | บทที่ 1: REST API แรก →

📌 อ่านก่อน — ควรผ่าน csharp/ มาถึงบท async มาก่อน async คือการเขียนโค้ดที่รอผล (เช่น รอ database ตอบ) โดยไม่บล็อกโปรแกรมทั้งตัว — สอนเต็มใน csharp/บทที่ 11 เล่มนี้ใช้ async ตั้งแต่ต้น ถ้ายังไม่เคยเห็น async/await มาก่อน ให้จำแค่ว่า: เวลาเห็นคำว่า async หน้า method และ await หน้าคำสั่งที่ต้องรอ (เช่น query database) แปลว่าโปรแกรมจะไปทำงานอื่นระหว่างรอ แทนที่จะหยุดนิ่งเฉย ๆ — พอผลลัพธ์มาค่อยกลับมาทำต่อจากจุดนั้น รายละเอียดจริงเรียนเต็มในบทที่ 11

🧱 เวอร์ชัน baseline ของหนังสือ (last reviewed: 2026-06 — ตรวจ release notes ทางการก่อนใช้) ตัวอย่างในเล่มใช้ syntax ระดับ .NET 8 LTS เป็นพื้น (คือเวอร์ชันต่ำสุดที่ตัวอย่างในเล่มนี้ยังใช้งานได้ — รันได้ไม่ error) — ตัวอย่างควรรันได้บน .NET 9 และ .NET 10 ด้วย และยกบาง API ของ .NET 9 STS (เช่น AddOpenApi) มาเสริมเป็นจุด ๆ

สำหรับโปรเจกต์ใหม่ปี 2026: แนะนำติดตั้ง .NET 10 LTS (GA ปลายปี 2026) แทน .NET 8 — syntax พื้นฐานเหมือนกัน แต่จะรับ support ยาวกว่า (.NET 8 EOL พฤศจิกายน 2026) ถ้ายังใช้ .NET 8 อยู่ ตัวอย่างทั้งหมดยังใช้ได้

CI/CD ในบทที่ 4 ตั้ง (pin = ตรึงเวอร์ชัน) ไว้ที่ 8.0.x เป็นค่าเริ่มต้นเพื่อรักษาความเข้ากันได้กับ LTS ตัวเก่า — ทีมคุณเปลี่ยนเป็นเวอร์ชันที่ใช้จริงได้

หมายเหตุเรื่องเวอร์ชัน:

  • .NET 8 LTS ยัง support ถึงพฤศจิกายน 2026
  • .NET 10 LTS GA (General Availability — ปล่อยใช้จริง) ปลายปี 2026 และ syntax พื้นฐานเหมือนเดิม — แนะนำสำหรับโปรเจกต์ใหม่
  • ก่อนอัปเดตเวอร์ชัน ให้เช็ค breaking change (การเปลี่ยนที่ทำให้โค้ดเก่าพัง) ใน release notes ก่อนเสมอ

🧭 บทนี้ปูภาพรวมก่อน — ส่วนต้น ๆ จะอธิบายแนวคิดพื้นฐาน (pipeline = สายท่อที่ request วิ่งผ่าน, DI = Dependency Injection การฉีด dependency ให้อัตโนมัติ) ซึ่งช่วยให้เข้าใจบทถัด ๆ ไป ถ้าอยากลงมือเขียนโค้ดเลย ข้ามไปที่ส่วน "Hello World" (หัวข้อ 14) หรือ Checkpoint ท้ายบทได้ แล้วค่อยย้อนกลับมาอ่านทฤษฎีทีหลัง — ลำดับหัวข้อจริงไม่ได้เปลี่ยน แค่ชี้ทางลัดให้

API (Application Programming Interface) = ช่องทางให้โปรแกรมคุยกัน เช่น เว็บหน้าบ้านยิงคำขอมาขอข้อมูลจากเซิร์ฟเวอร์

ASP.NET Core คือ framework (ชุดเครื่องมือสำเร็จรูป) ที่หนังสือเล่มนี้ใช้เขียน API ด้วยภาษา C# — ส่วน "ASP.NET Framework" ที่จะเทียบให้ดูในหัวข้อถัดไป คือรุ่นเก่าก่อนหน้านี้ (ปิดตัวไปแล้ว ไม่แนะนำให้ใช้กับโปรเจกต์ใหม่)

ก่อนเขียน API บรรทัดแรก เราจะตอบคำถาม 5 ข้อ:

  1. ASP.NET Core ต่างจาก ASP.NET Framework เก่ายังไง
  2. Host + Pipeline + DI ทำงานยังไง
  3. Kestrel คืออะไร — ทำไมเร็ว
  4. Minimal API vs Controller — เลือกอะไร
  5. เทียบ ASP.NET Core vs Spring Boot vs Express/NestJS

1. ประวัติฉบับย่อ

ASP.NET Framework (เก่า, 2002-2018) — Windows only (รันได้แต่ Windows), IIS (Internet Information Services — web server ของ Windows) integration ลึก, monolith (ระบบก้อนเดียวขนาดใหญ่) ใหญ่

ASP.NET Core (2016+) — เขียนใหม่หมด:

  • Cross-platform (ทำงานข้ามระบบปฏิบัติการ Win/Linux/Mac)
  • Modular (เลือก middleware ที่ใช้ — ตัวคั่นกลางที่ประมวลผล request, อธิบายต่อหัวข้อ 2)
  • Built-in DI (มี Dependency Injection ในตัว — การฉีด dependency ให้อัตโนมัติ, อธิบายหัวข้อ 3)
  • Embedded web server (มี web server ฝังมาในตัว ชื่อ Kestrel)
  • เร็วกว่า ASP.NET Framework เก่ามาก (ตัวเลข exact ขึ้นกับ workload — ดู Microsoft blog "Performance Improvements in .NET" รายปี และ TechEmpower round ล่าสุดเพื่อตัวเลขที่อ้างได้)

ในหนังสือเล่มนี้ "ASP.NET" = ตัวใหม่ (Core) เสมอ


2. Request Pipeline — Middleware

Middleware = ตัวคั่นกลางที่ประมวลผล request ระหว่างทาง ก่อนถึงโค้ดหลัก (เช่น ตรวจ token, redirect เป็น HTTPS, log)

Middleware ทำงานเรียงเป็นชั้น ๆ ทั้งขาเข้าและขากลับ ลองนึกภาพแบบนี้:

  • ขาเข้า — request เหมือนจดหมายที่ต้องผ่านด่านหลายชั้นก่อนถึงปลายทาง (โค้ดที่ตอบจริง) ด่านแรกตรวจอย่างหนึ่งแล้วส่งต่อด่านสอง ด่านสองตรวจอีกอย่างแล้วส่งต่อด่านสาม ไปเรื่อย ๆ
  • ขากลับ — พอตอบเสร็จ คำตอบ (response) เดินทางย้อนกลับผ่านด่านเดิมทีละชั้นจนถึง client
  • รูปทรง — ลักษณะ "เข้าทีละชั้น–ออกย้อนชั้น" นี้เหมือน ตุ๊กตาแม่ลูกดก (matryoshka / Russian doll pattern) ที่ซ้อนกันเป็นชั้น ๆ

Middleware = function ที่ "ครอบ" handler (handler = โค้ดที่ตอบ request จริง) — นี่คือ matryoshka / Russian doll pattern ที่อธิบายไว้ข้างบน

ลำดับการลงทะเบียน middleware = ลำดับการทำงาน → สำคัญมาก (ลงทะเบียนก่อน = ทำงานก่อน)


3. Built-in Dependency Injection

Dependency Injection (DI — การฉีด dependency ให้อัตโนมัติ) = แทนที่จะให้ class สร้างของที่มันต้องใช้เอง เราบอก framework ว่า class นี้ต้องใช้อะไร แล้ว framework "ฉีด" ให้ตอนสร้าง

เหมือนสั่งอาหารในร้าน — แทนที่คุณจะลุกไปหาวัตถุดิบมาทำอาหารเอง คุณแค่บอกว่าอยากได้อะไร แล้วคนเสิร์ฟนำมาให้

ข้อดีคือสลับ implementation (เช่นเปลี่ยนจากฐานข้อมูลจริงเป็นตัวปลอมตอนเทสต์) และเขียน test ได้ง่ายขึ้นมาก (ลงลึกในบทที่ 7)

ASP.NET Core มี DI container (ตัวเก็บและแจกจ่าย service ในแอป — ในที่นี้ไม่ใช่ Docker container) ในตัว — ไม่ต้องใช้ library ภายนอกอย่าง Autofac/Ninject เหมือนสมัยเก่า

csharp
var builder = WebApplication.CreateBuilder(args);

// IClock, IUserRepository, IPriceCalculator คือ interface (สัญญาว่าจะมี method บางอย่าง)
// ชื่อขึ้นต้นด้วย I ตามขนบ C# — ดูเพิ่มใน csharp/บท OOP
builder.Services.AddSingleton<IClock, SystemClock>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IPriceCalculator, PriceCalculator>();   // helper เล็ก ๆ ไม่มี state

💡 ของใหม่ใน .NET 8+TimeProvider (อยู่ใน System) เป็น abstraction สำหรับเวลาที่ Microsoft แนะนำให้ใช้ในโปรเจกต์ใหม่แทน IClock ที่เขียนเอง (test เวลา fake ได้ง่ายในตัว) ตัวอย่าง IClock ข้างบนเก็บไว้เพื่อสื่อแนวคิด

Lifetime (อายุของ instance — สร้างใหม่บ่อยแค่ไหน) 3 แบบ:

ก่อนดูตาราง: stateless service = service ที่ไม่เก็บสถานะระหว่างการเรียก เรียกกี่ครั้งผลก็เหมือนเดิม (เช่น ตัวคำนวณราคา ที่รับ input → คืน output โดยไม่จำอะไร) cache = ที่พักข้อมูลไว้ใช้ซ้ำเพื่อไม่ต้องคำนวณหรือ query ใหม่

Lifetimeสร้างเมื่อใช้กับ
Singletonครั้งเดียวต่อ app (ใช้ตัวเดิมตลอด)stateless service, config, cache
Scopedครั้งเดียวต่อ HTTP requestDB context (ตัวเชื่อม database), request data
Transientทุกครั้งที่ inject (ฉีดทีไรสร้างใหม่ทุกที)lightweight helper (ตัวช่วยเล็ก ๆ)

⚠️ กับดักที่เจอบ่อยที่สุด — Singleton ห้าม depend (พึ่งพา) บน Scoped ตรง ๆ (เช่น Singleton inject DbContext ที่เป็น Scoped) เพราะ Scoped จะติดอยู่ใน Singleton ยาวเกินอายุที่ควร (เรียกว่า captive dependency) ถ้าจำเป็นต้องใช้ ให้ inject IServiceScopeFactory แทน — เรื่องนี้ลึกในบทที่ 7

ดูลึกในบทที่ 7


4. Kestrel — Web Server

Kestrel = web server ที่ Microsoft เขียนใหม่ใน C#:

  • async I/O ตั้งแต่ต้น (จัดการ input/output แบบไม่บล็อก รับงานหลายอย่างพร้อมกันได้)
  • ใช้ Span/Memory<T> ลด allocation[^alloc] (ข้ามส่วนนี้ได้ถ้ายังไม่คุ้นเรื่อง memory) — ปกติเวลาตัดข้อความยาวออกมาเป็นชิ้นเล็ก โค้ดทั่วไปจะคัดลอกข้อมูลไปสร้าง array ใหม่ แต่ Span/Memory<T> คือ type ที่ชี้ไปดูข้อมูลก้อนเดิมในหน่วยความจำโดยตรง (ไม่คัดลอก) จึงเร็วกว่าและกิน memory น้อยกว่า
  • รองรับ HTTP/1.1, HTTP/2, HTTP/3 (QUIC — โปรโตคอลขนส่งข้อมูลรุ่นใหม่ที่เร็วกว่า)

TechEmpower benchmark[^bench]: Kestrel + minimal API ติดอันดับท็อปของโลกในหลาย round (โดยเฉพาะ plain text/JSON workload) (ตัวเลขอันดับและ throughput exact ขึ้นกับ round + workload + hardware — เช็ค round ล่าสุดที่ techempower.com/benchmarks ก่อนอ้างกับทีม flagged 2026-06)

ใน production (สภาพแวดล้อมใช้งานจริง) มักวาง reverse proxy[^revproxy] (Nginx/Traefik/YARP) หน้า Kestrel เพื่อ TLS termination (จุดที่ถอดรหัส HTTPS), caching — ดู devops/08-nginx-deep.md

[^alloc]: allocation = การจองหน่วยความจำเพื่อสร้าง object ใหม่ ยิ่งจองบ่อย ตัวเก็บขยะ (garbage collector) ยิ่งต้องทำงานหนัก แอปจึงช้าลง การลด allocation = ทำให้เร็วขึ้น [^bench]: benchmark = การทดสอบวัดประสิทธิภาพแล้วเทียบกัน หน่วย req/s = requests per second (จำนวนคำขอที่รับไหวต่อวินาที) ยิ่งสูงยิ่งรับโหลดได้มาก [^revproxy]: reverse proxy = เซิร์ฟเวอร์ตัวกลางที่รับ request จากภายนอกแล้วส่งต่อให้แอปข้างหลัง ช่วยทำ HTTPS, แคช, กระจายโหลด


5. Hosting Model

ทุกแอป ASP.NET Core เริ่มจากโครงสร้างเดียวกัน — สร้าง builder (อ่าน config + register DI), Build() ได้ WebApplication, ตั้ง middleware/route แล้ว Run() เข้าใจลำดับ 6 ขั้นนี้แล้วจะอ่านโค้ด startup ของโปรเจกต์ใดก็ออก:

csharp
var builder = WebApplication.CreateBuilder(args);
// สร้างและลงทะเบียน service ต่าง ๆ...
var app = builder.Build();
// ตั้งค่า pipeline (สายท่อ middleware)...
app.Run();

ลำดับ:

  1. CreateBuilder = อ่าน config (จาก env variable, appsettings.json)
  2. builder.Services.Add... = ลงทะเบียน service เข้า DI
  3. builder.Build() = สร้าง WebApplication
  4. app.Use... = ตั้งค่า middleware
  5. app.Map... = กำหนด route (เส้นทาง URL → handler)
  6. app.Run() = เริ่มฟัง request

6. Minimal API vs Controller

Minimal API (.NET 6+)

csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello!");
app.MapGet("/users/{id}", (int id) => new { Id = id, Name = "Alice" });
app.MapPost("/users", (CreateUserDto dto) => Results.Created($"/users/1", dto));

app.Run();

Controller

csharp
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    [HttpGet]
    public IActionResult List() => Ok(new[] { /*...*/ });

    [HttpGet("{id}")]
    public IActionResult Get(int id) => Ok(new { Id = id });
}

เลือกอย่างไร:

Minimal APIController
ขนาดสั้นยาวกว่า
Feature ครบใกล้เคียง Controller ใน .NET 8+ (รองรับ filter, attribute routing, model binding ส่วนใหญ่)เต็ม โดยเฉพาะ MVC สมัยเก่า
Performanceเร็วกว่าเล็กน้อยกลาง
เหมาะกับmicroservice, prototype (ตัวต้นแบบ), simple APIระบบใหญ่, complex routing (การจัดเส้นทาง URL ซับซ้อน), งาน MVC แบบ classic

ศัพท์ที่ใช้ในตาราง:

  • filter = ตัวกรองที่รันก่อน/หลัง handler เช่นตรวจ permission
  • model binding = การแปลงข้อมูลจาก request (query string, body) เป็น parameter ของ method อัตโนมัติ

คำแนะนำ: ใช้ Minimal เป็น default (ค่าตั้งต้น) — switch มา Controller เมื่อต้องการ feature ที่ขาด (filter เยอะ, model binder ซับซ้อน)


7. ASP.NET Core vs ตัวอื่น

Spring BootASP.NET CoreNestJSExpress
LanguageJavaC#TSJS
DI built-in
วิธีกำกับโค้ด (Convention)[^conv]annotationattributedecoratorfunction
Performance (req/s)[^bench]สูงมากสูงมาก (Native AOT[^aot] ช่วยอีก)กลาง-สูงกลาง
Learning curve (ความชันของการเรียนรู้)สูงกลางกลางต่ำ
Job market (Asia/EU)สูงสูง enterprise (องค์กรใหญ่)กลางสูง
Modern featureกลางสูงสุดสูงกลาง

ใกล้กับ Spring Boot ที่สุดในแง่แนวคิดการออกแบบ (design approach) — แต่ syntax (รูปแบบการเขียนโค้ด) สั้นกว่า เพราะ C#

📊 เรื่อง performance — ตัวเลข req/s จาก benchmark ลอย ๆ เปรียบเทียบกันตรง ๆ ไม่ได้ (ขึ้นกับ hardware, workload — plain text/JSON/DB-bound, version ของ framework, GC settings) ใช้ตารางนี้ดูภาพรวมเชิงคุณภาพ แล้วทดสอบกับ workload จริงของคุณก่อนตัดสินใจ — เช็ค TechEmpower round ล่าสุดถ้าอยากเทียบกันแบบแฟร์ (เงื่อนไขเดียวกันทุกฝั่ง) (flagged 2026-06)

[^conv]: annotation / attribute / decorator = ป้ายกำกับที่แปะบนโค้ด (class, method) เพื่อบอก framework ว่าให้ทำอะไรพิเศษ เป็นแนวคิดเดียวกันแต่ละภาษาเรียกต่างกัน: - Java เรียก annotation เช่น @GetMapping - C# เรียก attribute เช่น [HttpGet] - TypeScript เรียก decorator เช่น @Get() [^aot]: Native AOT (Ahead-Of-Time compilation) = การแปลงโค้ดเป็นไฟล์ native (เครื่องรันได้ตรง ๆ) ตั้งแต่ตอน build แทนที่จะแปลตอนรัน ทำให้แอปเริ่มเร็วและใช้ memory น้อยลง (ลงรายละเอียดในบทที่ 5)


8. Configuration

ASP.NET Core อ่าน config (ค่าตั้งค่า) จากหลายแหล่ง (override กันตามลำดับ — แหล่งหลังทับแหล่งหน้า):

  1. appsettings.json
  2. appsettings.{Environment}.json (เช่น appsettings.Development.json)
  3. Environment variables (ตัวแปรสภาพแวดล้อมของระบบ)
  4. Command-line args (ค่าที่ส่งตอนสั่งรันจาก terminal)
  5. User secrets (ที่เก็บความลับเฉพาะเครื่อง dev)
  6. Azure Key Vault / AWS SSM (ที่เก็บความลับสำหรับ production)
jsonc
// appsettings.json
{
  "Logging": {
    "LogLevel": { "Default": "Information" }
  },
  "ConnectionStrings": {
    "Default": "Host=localhost;Database=app;Username=pg;Password=pg"
  }
}
csharp
// อ่านค่า config ออกมาใช้
var cs = builder.Configuration.GetConnectionString("Default");
var logLevel = builder.Configuration["Logging:LogLevel:Default"];

Best practice (แนวทางที่แนะนำ): ใช้ Options pattern (เดี๋ยวบทที่ 7 อธิบาย) — strongly-typed config (config ที่ผูกกับ type ชัดเจน เขียนผิดจะรู้ตั้งแต่ compile)


9. Environment

ASP.NET Core รู้ว่ากำลังรันใน environment ไหนผ่านตัวแปร ASPNETCORE_ENVIRONMENT (Development/Staging/Production) — ทำให้โหลด config ต่างกันและเปิด/ปิดฟีเจอร์ตาม env ได้ (เช่นเปิด Swagger เฉพาะตอน dev) ส่วนนี้แสดงวิธีตั้งและใช้:

💡 OpenAPI คืออะไร — เอกสารอธิบาย endpoint ของ API แบบที่เครื่องอ่านได้ (machine-readable) สร้างอัตโนมัติจากโค้ด แล้วให้เครื่องมืออย่าง Swagger UI เอาไปแสดงผล/ให้ทดลองยิง request ได้ — โค้ดด้านล่างเปิดเอกสารนี้เฉพาะตอน dev

powershell
# Windows (PowerShell) — ตั้งค่า environment variable
$env:ASPNETCORE_ENVIRONMENT = "Development"
dotnet run
bash
# Linux / macOS
ASPNETCORE_ENVIRONMENT=Production dotnet run

ค่ามาตรฐาน: Development, Staging, Production

csharp
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();   // .NET 9+ built-in — เปิดเอกสาร API ที่ /openapi/v1.json
    // หมายเหตุ: ถ้าใช้ .NET 8 + Swashbuckle ใช้ app.UseSwagger(); app.UseSwaggerUI(); แทน
}

10. Project Templates

dotnet new มี template หลายแบบให้เริ่มโปรเจกต์ตามประเภทงาน — web API, MVC, Razor Pages, Blazor, gRPC, worker เลือกให้ตรงกับสิ่งที่จะสร้างจะได้โครงเริ่มต้นที่เหมาะ หนังสือนี้ใช้ webapi แบบ Minimal API เป็นหลัก:

bash
dotnet new web              # ขั้น minimal — แค่ Hello World
dotnet new webapi           # API (Minimal)
dotnet new webapi --use-controllers  # API (Controller)
dotnet new mvc              # MVC + views (สร้าง HTML ที่ฝั่ง server)
dotnet new razor            # Razor Pages
dotnet new blazorserver     # Blazor Server (เว็บโต้ตอบได้)
dotnet new blazor           # Blazor Web (.NET 8+, render แบบผสม)
dotnet new grpc             # gRPC service (โปรโตคอลเรียก service ข้ามเครื่องที่เร็ว)
dotnet new worker           # background service (บริการทำงานเบื้องหลัง)
dotnet new sln              # solution file (ไฟล์รวมหลายโปรเจกต์)

หนังสือนี้ใช้ webapi Minimal API เป็นหลัก


11. ลองโปรเจกต์แรก

ลงมือสร้างโปรเจกต์แรกกันเลย — สร้าง webapi, รัน แล้วเปิด endpoint ตัวอย่างใน browser เพื่อเห็นว่า ASP.NET Core ทำงานได้จริงในไม่กี่คำสั่ง ก่อนจะลงรายละเอียดในบทถัด ๆ ไป (dotnet คือ command-line tool ที่ใช้สร้าง/build/รันโปรเจกต์ .NET ส่วนคำที่ขึ้นต้นด้วย - หรือ -- คือ flag/option ที่ปรับพฤติกรรมคำสั่งนั้น เช่น -n ตั้งชื่อโปรเจกต์):

bash
dotnet new webapi -n Api --use-program-main   # .NET 8+ flag — สร้าง Program.cs ที่มี Main() แทน top-level statements
cd Api
dotnet run
# → port จะอ่านจาก Properties/launchSettings.json ของโปรเจกต์ (มักเป็น http://localhost:5xxx + https://localhost:7xxx)
# → มี endpoint ตัวอย่างชื่อ /weatherforecast มาให้

💡 top-level statements vs --use-program-main: top-level statements คือ C# 9+ feature ที่ให้เขียนโค้ดในไฟล์ได้โดยไม่ต้องมี class Program { static void Main() {...} } รอบนอก — เหมาะเขียนสั้น แต่เวลาเรียนรู้ --use-program-main ทำให้เห็นโครงสร้างชัดกว่า ในหนังสือนี้ใช้ทั้งสองแบบสลับกัน หน้าตาไฟล์ Program.cs ที่ template สร้างให้จริง ๆ จะอธิบายละเอียดใน บทที่ 1

ลองเปิด URL ที่ console พิมพ์ออกมา ตามด้วย /weatherforecast (เช่น http://localhost:5141/weatherforecast) ใน browser → จะได้ JSON array (ลิสต์ข้อมูลรูปแบบ JSON)


12. โครงสร้างไฟล์มาตรฐาน

โปรเจกต์ ASP.NET Core มีโครงสร้างไฟล์มาตรฐานที่ควรรู้จัก — Program.cs (entry + config), appsettings.json (config ต่อ env), โฟลเดอร์ Controllers/Models/Services และ launchSettings.json (โปรไฟล์ dev) คุ้นกับผังนี้แล้วจะหาของในโปรเจกต์ใดก็เจอ:

text
Api/
├── Api.csproj
├── Program.cs            ← จุดเริ่มโปรแกรม (entry point) + config
├── appsettings.json
├── appsettings.Development.json
├── Controllers/          ← ถ้าใช้ Controller
├── Models/
├── Services/
└── Properties/
    └── launchSettings.json  ← โปรไฟล์สำหรับ dev

13. NuGet packages ที่จะใช้บ่อย

NuGet = ระบบจัดการ library (แพ็กเกจโค้ดสำเร็จรูป) ของ .NET คล้าย npm ของ Node ติดตั้งด้วยคำสั่ง dotnet add package <ชื่อ> เช่น:

bash
dotnet add package Microsoft.AspNetCore.OpenApi

packages หลักที่จะใช้ในหนังสือนี้:

bash
# core
Microsoft.AspNetCore.OpenApi          # OpenAPI/Swagger (เอกสาร API อัตโนมัติ) — built-in ใน .NET 9+ ไม่ต้องใช้ Swashbuckle แล้ว

# database
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Npgsql.EntityFrameworkCore.PostgreSQL  # provider สำหรับ PostgreSQL หรือ
Microsoft.EntityFrameworkCore.SqlServer

# auth
Microsoft.AspNetCore.Authentication.JwtBearer
Microsoft.AspNetCore.Identity.EntityFrameworkCore

# logging
Serilog.AspNetCore                     # structured logging ที่นิยม (log แบบมีโครงสร้าง ค้นง่าย)

# testing
xunit
Microsoft.AspNetCore.Mvc.Testing
Testcontainers.PostgreSql

ติดตั้งทีหลัง — บทถัด ๆ ไปจะแนะนำเมื่อใช้


14. Hello World — full version

csharp
// Program.cs
var builder = WebApplication.CreateBuilder(args);

// ลงทะเบียน service เข้า DI
builder.Services.AddEndpointsApiExplorer();  // บอกให้ OpenAPI สแกนหา endpoint ที่เรากำหนดไว้ใน MapGet/MapPost (จำเป็นใน .NET 8 แต่ .NET 9+ ไม่ต้องแล้ว)
builder.Services.AddOpenApi();   // .NET 9+ — ถ้าใช้ .NET 8 SDK ต้อง `dotnet add package Microsoft.AspNetCore.OpenApi` ก่อน (ของเก่ากว่านั้นใช้ AddSwaggerGen จาก Swashbuckle)

var app = builder.Build();

// ตั้งค่า pipeline (สายท่อ middleware)
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();   // เปิดเอกสาร API ที่ /openapi/v1.json เฉพาะตอน dev
}

app.UseHttpsRedirection();   // บังคับเปลี่ยน http เป็น https

// กำหนด endpoint (เส้นทาง URL → โค้ดที่ตอบ)
app.MapGet("/", () => "Hello, World!");
app.MapGet("/health", () => Results.Ok(new { status = "ok" }));

app.Run();

3-4 ชั้น แต่ทุกชั้นมีหน้าที่ชัด — เดี๋ยวบทถัดไปจะเขียน REST API จริง


🛠️ Checkpoint 0 — ลงมือทำ

  1. dotnet new webapi -n MyApi --use-program-main → run
  2. เปิด /weatherforecast ใน browser
  3. ลบ default endpoint → เพิ่ม app.MapGet("/hello", () => "Hello!")
  4. ลอง dotnet run + เปิด /hello
  5. ตั้ง ASPNETCORE_ENVIRONMENT=Production → ดู endpoint /openapi/v1.json หาย (เพราะใน Hello World เรา map MapOpenApi() เฉพาะตอน Development)
    • หมายเหตุ: ถ้าเทมเพลตที่คุณสร้าง (scaffold) ด้วย dotnet new webapi เป็นเวอร์ชันที่ใช้ Swashbuckle จะเห็น /swagger UI หายแทน

สรุปบทที่ 0

  • ASP.NET Core = framework ใหม่ ตั้งแต่ .NET Core 1.0 — cross-platform + เร็วมาก
  • Pipeline = chain (สายต่อกัน) ของ middleware (ลำดับสำคัญ)
  • DI built-in มี 3 lifetime: Singleton/Scoped/Transient
  • Kestrel = web server ของ .NET (ติดอันดับ top tier ใน TechEmpower benchmark)
  • Minimal API (default) + Controller (สำหรับงานซับซ้อน)
  • Config มาจาก appsettings + env var + secret manager (ที่เก็บความลับ)

→ บทที่ 1: REST API แรก


🔤 Glossary · 📋 Style guide · 📅 last_verified: 2026-06-12