譯者 | 朱先忠
策劃 | 云昭
51CTO讀者成長計劃社群招募,咨詢小助手(微信號:TTalkxiaozhuli)
一、簡介
ChatGPT是由人工智能研究中心OpenAI創建的尖端自然語言處理模型,OpenAI公司是由埃隆·馬斯克、薩姆·奧特曼和格雷格·布羅克曼共同創辦的。該模型于2018年6月發布,并不斷進行修改和升級,最新版本GPT-3(https://openai.com/blog/gpt-3-Apps)于2020年發布。時下最火的ChatGPT是基于GPT-3模型開發而成,并于2022年發布。ChatGPT中的“GPT”代表“Generative Pre-trained Transformer”,即生成式預訓練轉換器,這是一種新式復雜的深度學習架構。ChatGPT本質上使用大量的文本數據來“學習”人類語言的復雜性,從而使之能夠創建常常無法與人類相區分的回復結果。ChatGPT技術基于一種稱為轉換器(Transformer)的神經網絡,非常適合自然語言處理應用。
ChatGPT的一個關鍵特性是,它能夠根據您在聊天框中給出的各種提示創建高質量的輸出。你得到的反應感覺就像是人類產生的。使用期間,您還可以指定請求的條件。該模型是在大量的文本語料庫基礎上訓練的,因此它可以依靠廣泛的數據來回答問題、提供信息或參與由其神經網絡生成的隨意對話。記憶是至關重要的;然而,ChatGPT并非完美無缺。當面臨超出模型知識范圍的建議時,模型可能會提供不合邏輯或不合適的答復。ChatGPT的使用率有時很高;因此,有時系統可能會限制您發送的查詢數量。
由于本文的主要目的是為各位提供一個全面而實際的示例,從而說明如何使用ChatGPT為REST API生成代碼;因此,現在讓我們首先了解一下REST API是什么。REST API是一種web服務,允許兩個計算機系統通過遵循一組標準化規則在互聯網上進行通信。它遵循REST體系結構,該體系結構以其無狀態和客戶端-服務器的特性而聞名。REST API的工作原理是客戶端使用特定的URL和HTTP方法(如GET、POST、PUT或DELETE)向服務器發送請求,服務器用包含請求的數據或指示請求的操作是否成功的消息進行響應。REST API在現代web和移動應用程序中廣泛使用,因為它們提供了在系統之間交換數據的標準化和高效方法。您通常可以通過閱讀文檔來了解有關特定API的更多信息。其中,有些API是商業性的,通常有不同的定價計劃。這也意味著,發出有關API請求是需要特定Bearer令牌的。
現在,我們來關注最有趣的部分,即在ChatGPT的幫助下,我們將嘗試使用C#語言來創建一個功能齊全的REST API來實現學生信息的管理。
二、創建API
在本節中,我們將讓ChatGPT編寫一個用于管理學生的功能完備的REST API,包括創建、刪除和修改學生記錄等功能。要做到這一點,我們應該先建立一個“學生控制器(StudentsController)”,該控制器將具有API端點,還有一個“學生類(Student)”,該類將具有所需的字段,如Id、名稱和年齡等。我們在這里的唯一工作是生成邏輯性及結構良好的查詢,隨著我們逐步構建API,這些查詢將變得越來越復雜。讓我們開始吧。
三、用C#語言編寫用于管理學生的REST API
下面是一個用C#管理學生的RESTful API示例。此API將使用HTTP方法GET、POST、PUT和DELETE對學生資源列表執行CRUD(創建、讀取、更新、刪除)操作。
首先,讓我們定義一個“學生類”來表示學生資源:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
接下來,讓我們創建一個StudentsController類來處理HTTP請求:
[Route("api/students")]
public class StudentsController : Controller
{
private static List<Student> students = new List<Student>
{
new Student { Id = 1, Name = "John Smith", Age = 20, Email = "john.smith@example.com" },
new Student { Id = 2, Name = "Jane Doe", Age = 19, Email = "jane.doe@example.com" },
new Student { Id = 3, Name = "Bob Johnson", Age = 21, Email = "bob.johnson@example.com" }
};
[HttpGet]
public IActionResult GetAllStudents()
{
return Ok(students);
}
[HttpGet("{id}")]
public IActionResult GetStudent(int id)
{
var student = students.FirstOrDefault(s => s.Id == id);
if (student == null)
{
return NotFound();
}
return Ok(student);
}
[HttpPost]
public IActionResult CreateStudent([FromBody] Student student)
{
student.Id = students.Max(s => s.Id) + 1;
students.Add(student);
return CreatedAtAction(nameof(GetStudent), new { id = student.Id }, student);
}
[HttpPut("{id}")]
public IActionResult UpdateStudent(int id, [FromBody] Student student)
{
var existingStudent = students.FirstOrDefault(s => s.Id == id);
if (existingStudent == null)
{
return NotFound();
}
existingStudent.Name = student.Name;
existingStudent.Age = student.Age;
existingStudent.Email = student.Email;
return NoContent();
}
[HttpDelete("{id}")]
public IActionResult DeleteStudent(int id)
{
var student = students.FirstOrDefault(s => s.Id == id);
if (student == null)
{
return NotFound();
}
students.Remove(student);
return NoContent();
}
此StudentsController類定義以下端點:
- GET /api/students:返回所有學生的列表。
- GET /api/students/{id}:按id返回單個學生資源。
- POST /api/students:創建一個新的學生資源。
- PUT /api/students/{id}:按id更新現有學生資源。
- DELETE /api/students/{id}:按id刪除現有的學生資源。
注意:對于CreateStudent和UpdateStudent方法,我們使用[FromBody]屬性將請求體反序列化為Student對象。
還要注意,學生列表是靜態的,并用一些示例數據進行了初始化。但是,在真實場景中,這些數據可能存儲在數據庫或其他持久性存儲中。
最后,我們使用HTTP狀態代碼200 OK、201 Created、204 No Content和404 Not Found來指示每個操作的結果。
四、向Student類添加更多屬性
以下是Student類的更新版本,其中包含一些附加的屬性:
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
}
在該類的更新版本中,我們添加了以下屬性:
- FirstName:學生的名字。
- LastName:學生的姓。
- Address:學生的街道地址。
- City:學生居住的城市。
- State:學生所在的州。
- ZipCode:學生地址的郵政編碼。
這些附加的屬性可以提供有關學生的更多信息,并可用于API中的篩選、排序和搜索操作。
五、將另一個屬性添加到Student類
關于學生所學的科目
以下是Student類的更新版本,其中包含學生所學科目的附加屬性:
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public List<string> SubjectsTaken { get; set; }
}
在這個更新版本的類中,我們添加了一個名為SubjectsTaken的屬性,它是一個字符串列表,表示學生所學科目的名稱。此屬性可用于按學生所學科目查詢和篩選學生。
您可以像這樣向列表中添加科目:
var student = new Student
{
Id = 1,
FirstName = "John",
LastName = "Doe",
Age = 20,
Email = "john.doe@example.com",
Address = "123 Main St",
City = "Anytown",
State = "CA",
ZipCode = "12345",
SubjectsTaken = new List<string> { "Math", "Science", "History" }
};
而且,您可以像這樣檢索給定學生的科目列表:
var student = GetStudent(1);
var subjects = student.SubjectsTaken;
六、將SubjectTake更改為名為Subject的對象
包含屬性Id、Name、Teacher和Credits
以下是Student類的更新版本,其中SubjectsTaken屬性被替換為包含Id、Name、Teacher和Credits屬性的新對象Subject:
public class Subject
{
public int Id { get; set; }
public string Name { get; set; }
public string Teacher { get; set; }
public int Credits { get; set; }
}
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public List<Subject> SubjectsTaken { get; set; }
}
在這個類的更新版本中,我們用包含Id、Name、Teacher和Credits屬性的新對象Subject替換了SubjectsTaken屬性。這種新結構可以提供有關學生所學科目的更詳細信息,并且可以用于根據特定科目的屬性篩選和查詢學生。
您可以將科目添加到SubjectsTaken列表,如下所示:
var student = new Student
{
Id = 1,
FirstName = "John",
LastName = "Doe",
Age = 20,
Email = "john.doe@example.com",
Address = "123 Main St",
City = "Anytown",
State = "CA",
ZipCode = "12345",
SubjectsTaken = new List<Subject>
{
new Subject { Id = 1, Name = "Math", Teacher = "Mr. Smith", Credits = 4 },
new Subject { Id = 2, Name = "Science", Teacher = "Ms. Jones", Credits = 3 }
}
};
您可以檢索給定學生的科目列表,如下所示:
var student = GetStudent(1);
var subjects = student.SubjectsTaken;
七、將Student類中的State屬性更改為枚舉類型
public enum State
{
AL, AK, AZ, AR, CA, CO, CT, DE, FL, GA, HI, ID, IL, IN, IA, KS, KY, LA, ME,
MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NY, NC, ND, OH, OK, OR, PA,
RI, SC, SD, TN, TX, UT, VT, VA, WA, WV, WI, WY
}
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public State State { get; set; }
public string ZipCode { get; set; }
public List<Subject> SubjectsTaken { get; set; }
}
在該類的更新版本中,我們用名為State的枚舉替換了State屬性。State枚舉包含狀態縮寫列表,并為State屬性提供類型安全性。
您可以這樣設置學生的State屬性:
var student = new Student
{
Id = 1,
FirstName = "John",
LastName = "Doe",
Age = 20,
Email = "john.doe@example.com",
Address = "123 Main St",
City = "Anytown",
State = State.CA,
ZipCode = "12345",
SubjectsTaken = new List<Subject>
{
new Subject { Id = 1, Name = "Math", Teacher = "Mr. Smith", Credits = 4 },
new Subject { Id = 2, Name = "Science", Teacher = "Ms. Jones", Credits = 3 }
}
};
您可以像這樣檢索給定學生的State屬性:
var student = GetStudent(1);
var state = student.State;
八、為必填項ID、FirstName和EmailID添加校驗器
以下是Student類的更新版本,其中包括Id、FirstName和Email屬性的驗證:
public class Student
{
private int _id;
private string _firstName;
private string _email;
public int Id
{
get { return _id; }
set
{
if (value <= 0)
{
throw new ArgumentException("Id must be greater than zero.");
}
_id = value;
}
}
public string FirstName
{
get { return _firstName; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("First name cannot be null or empty.");
}
_firstName = value;
}
}
public string LastName { get; set; }
public int Age { get; set; }
public string Email
{
get { return _email; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Email cannot be null or empty.");
}
_email = value;
}
}
public string Address { get; set; }
public string City { get; set; }
public State State { get; set; }
public string ZipCode { get; set; }
public List<Subject> SubjectsTaken { get; set; }
}
在這個類的更新版本中,我們為Id、FirstName和Email屬性添加了私有字段,并為其相應的setter方法添加了驗證邏輯。Id屬性必須大于零,FirstName和Email屬性不能為null或空。如果任何這些驗證檢查失敗,將引發ArgumentException異常。
您可以像這樣創建一個新的學生對象:
var student = new Student
{
Id = 1,
FirstName = "John",
LastName = "Doe",
Age = 20,
Email = "john.doe@example.com",
Address = "123 Main St",
City = "Anytown",
State = State.CA,
ZipCode = "12345",
SubjectsTaken = new List<Subject>
{
new Subject { Id = 1, Name = "Math", Teacher = "Mr. Smith", Credits = 4 },
new Subject { Id = 2, Name = "Science", Teacher = "Ms. Jones", Credits = 3 }
}
};
如果嘗試使用無效數據創建新的學生對象,將引發ArgumentException異常:
var invalidStudent = new Student
{
Id = 0, // throws ArgumentException
FirstName = "", // throws ArgumentException
LastName = "Doe",
Age = 20,
Email = "", // throws ArgumentException
Address = "123 Main St",
City = "Anytown",
State = State.CA,
ZipCode = "12345",
SubjectsTaken = new List<Subject>()
};
九、使StudentsController控制器異步
這里是StudentsController類的更新版本,它使用異步方法:
[ApiController]
[Route("api/[controller]")]
public class StudentsController : ControllerBase
{
private readonly IStudentRepository _studentRepository;
public StudentsController(IStudentRepository studentRepository)
{
_studentRepository = studentRepository;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Student>>> GetAllStudents()
{
var students = await _studentRepository.GetAllStudentsAsync();
return Ok(students);
}
[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudentById(int id)
{
var student = await _studentRepository.GetStudentByIdAsync(id);
if (student == null)
{
return NotFound();
}
return Ok(student);
}
[HttpPost]
public async Task<ActionResult<Student>> CreateStudent(Student student)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await _studentRepository.AddStudentAsync(student);
return CreatedAtAction(nameof(GetStudentById), new { id = student.Id }, student);
}
[HttpPut("{id}")]
public async Task<IActionResult> UpdateStudent(int id, Student student)
{
if (id != student.Id)
{
return BadRequest();
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var existingStudent = await _studentRepository.GetStudentByIdAsync(id);
if (existingStudent == null)
{
return NotFound();
}
await _studentRepository.UpdateStudentAsync(student);
return NoContent();
}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteStudent(int id)
{
var existingStudent = await _studentRepository.GetStudentByIdAsync(id);
if (existingStudent == null)
{
return NotFound();
}
await _studentRepository.DeleteStudentAsync(existingStudent);
return NoContent();
}
}
在該類的更新版本中,我們將異步關鍵字async添加到與IStudentRepository交互的操作方法中。我們還在調用異步方法之前添加了await關鍵字,以等待結果完成后再繼續。
如果action方法返回一個值,我們將其包裝為ActionResult<T>類型,其中“T”是返回值的類型。如果發生錯誤,我們將返回適當的ActionResult,例如BadRequest()或NotFound()。
注意:IStudentRepository接口也必須更新,以包含其方法的異步版本。以下是更新后的IStudentRepository的示例:
public interface IStudentRepository
{
Task<IEnumerable<Student>> GetAllStudentsAsync();
Task<Student> GetStudentByIdAsync(int id);
Task AddStudentAsync(Student student);
Task UpdateStudentAsync(Student student);
Task DeleteStudentAsync(Student student);
}
在這個版本的接口中,我們為每個方法添加了異步關鍵字,并將返回類型更改為Task<T>,其中“T”是返回值的類型。這允許調用代碼使用await關鍵字等待方法完成。
十、結論
在本文中,我們使用ChatGPT構建了一個REST API,這是使用ASP.NET Core和C#編程語言實現的,用于實現學生信息的管理。此API僅是一個Web服務的基本實現版本,它通過提供幾個不同的端點來實現CRUD(創建、讀取、更新、刪除)操作,以管理學生列表。實現過程中,ChatGPT能夠向Student類添加基本驗證,并使代碼異步。除此之外,當我們需要Subject屬性的新對象時,這個AI工具能夠很容易將狀態屬性的類型更改為枚舉類型,并創建了一個全新的類。總之,它工作得很好,創建了功能齊全的類、控制器和存儲庫。
在我看來,ChatGPT應該被視為編程輔助工具,尤其是對于簡單和重復的任務,因為它可以使這些任務自動化,并推薦更高效和有效的編程技術。因此,它可以使程序員節省時間,從而使他們可以利用這些時間來解決更具挑戰性和創造性的編程任務。然而,我也認為,使用它作為人類編程技能的補充,而不是替代是很重要的,因為它通常無法在復雜的情況下提供最佳解決方案。
至于ChatGPT的威力,我相信這篇文章足以證明。如果你是開發人員,可以將ChatGPT用于其他各種場景下,例如驗證或測試代碼。你甚至可以使用它在Python/ target=_blank class=infotextkey>Python中生成代碼。當前,許多公司已經在研究將ChatGPT集成到其平臺上的方法了。
總之,ChatGPT是一種令人印象深刻的人工智能語言模型,它有可能徹底改變我們的編程方式,雖然它可能無法完全取代人類程序員,不過這個模型一定可以被視為一種寶貴的輔助資源來使用。
原文鏈接:??https://dzone.com/articles/create-a-rest-api-in-c-using-chatgpt??
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。