C# / .NETDevOpsMisc
C# / .NET
Write a REST API in C# using Chat GPT
Alexandru Puiu
Alexandru Puiu
December 08, 2022
4 min

Table Of Contents

01
Write integration api documentation
02
Write an API code sample in C#
03
Create a REST API in C# to manage customers
04
Add the following properties to the customer: Birth date, address, phone numbers and email
05
Change Address to an object containing the properties Address, Address2, City, State, Zipcode
06
Add Country to the address, but make it an enum of all countries
07
Add validation to make the country, name and email required
08
Write a customers REST API in C# where the customer has the properties Id, Name, Birth Date, Phone numbers, email, an Address object with Address1, address2, city, state, zipcode and a country enum, and add validation to the api
09
Make it async

Last night I decided to check out Chat GPT and see how far along it is, and I was blown away.

I’ve used GPT-3 based systems like RYTR for expanding ideas, marketing headlines, and played around with it for writing all sorts of content to see what it can do. But Chat GPT is the first model I can see myself really using in my day-to-day to write production code. Do I see it replacing me? Not really, but not because it can’t. I think the industry will adopt it, and the landscape will change in a way as significant to the industrial revolution.

So far I had it create a business plan, marketing plan, even wrote a poem, but the coding part is the one of interest here, so here’s what my conversation looked like:

Write integration api documentation

Sure, here’s a rough outline for integration API documentation:

Introduction: This section should provide an overview of the API, including its purpose, features, and requirements.

Authentication: This section should describe the authentication methods and requirements for accessing the API, such as API keys or OAuth tokens.

Endpoints: This section should list and describe the available API endpoints, including their URLs, methods (e.g. GET, POST), and parameters.

Request and response examples: This section should provide examples of API requests and responses, including the request format, parameters, and possible response codes and data.

Error handling: This section should describe the error codes and messages that may be returned by the API, and how to handle them in the client application.

Versioning: This section should describe how the API is versioned, and how to specify the desired API version in the request.

Deprecation: This section should describe the process for deprecating old API versions and transitioning to newer versions.

Contact information: This section should provide contact information for the API team, including support email or web form, and a link to the API’s terms of use and privacy policy.

Overall, the goal of the integration API documentation is to provide clear and detailed information about the API, so that developers can easily integrate it into their applications and use it to access the API’s features and data. The documentation should be well-organized and easy to understand, with clear examples and error handling information.

Write an API code sample in C#

Sure, here's a sample API code in C#:
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace MyAPI
{
    public class MyAPI
    {
        private readonly HttpClient _httpClient;

        public MyAPI(string apiKey)
        {
            _httpClient = new HttpClient
            {
                BaseAddress = new Uri("https://myapi.com/v1/")
            };
            _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
        }

        public async Task<string> GetDataAsync(string id)
        {
            var response = await _httpClient.GetAsync($"data/{id}");
            if (response.StatusCode == HttpStatusCode.OK)
            {
                return await response.Content.ReadAsStringAsync();
            }

            throw new Exception("Error retrieving data from API");
        }
    }
}

Create a REST API in C# to manage customers

using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MyAPI
{
    public class CustomersController : ApiController
    {
        private static readonly List<Customer> Customers = new List<Customer>
        {
            new Customer { Id = 1, Name = "John Doe" },
            new Customer { Id = 2, Name = "Jane Doe" },
            new Customer { Id = 3, Name = "Robert Smith" }
        };

        public IEnumerable<Customer> Get()
        {
            return Customers;
        }

        public Customer Get(int id)
        {
            return Customers.SingleOrDefault(c => c.Id == id);
        }

        public void Post([FromBody] Customer customer)
        {
            Customers.Add(customer);
        }

        public void Put(int id, [FromBody] Customer customer)
        {
            var existingCustomer = Customers.SingleOrDefault(c => c.Id == id);
            if (existingCustomer != null)
            {
                existingCustomer.Name = customer.Name;
            }
        }

        public void Delete(int id)
        {
            Customers.RemoveAll(c => c.Id == id);
        }
    }

    public class Customer
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }
}

This code defines a CustomersController class that exposes a set of RESTful API endpoints for managing customers. It includes methods for GET, POST, PUT, and DELETE requests, which allow clients to retrieve a list of customers, retrieve a single customer by ID, create a new customer, update an existing customer, and delete a customer.

The Customers property is a static list of Customer objects that will be used to store the customer data. This list is initialized with some sample data, but in a real-world application, this data would typically be stored in a database.

The Get method is used to handle both the GET /customers and GET /customers/{id} requests. When called without an ID parameter, it returns the entire list of customers. When called with an ID parameter, it returns the customer with the specified ID, or null if no such customer exists.

The Post method is used to handle the POST /customers request, which creates a new customer based on the data in the request body. It adds the new customer to the `

Add the following properties to the customer: Birth date, address, phone numbers and email

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MyAPI
{
    public class CustomersController : ApiController
    {
        private static readonly List<Customer> Customers = new List<Customer>
        {
            new Customer
            {
                Id = 1,
                Name = "John Doe",
                BirthDate = new DateTime(1990, 1, 1),
                Address = "123 Main St",
                PhoneNumbers = new List<string> { "555-555-1212", "555-555-1213" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 2,
                Name = "Jane Doe",
                BirthDate = new DateTime(1995, 5, 15),
                Address = "456 Park Ave",
                PhoneNumbers = new List<string> { "555-555-2121", "555-555-2122" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 3,
                Name = "Robert Smith",
                BirthDate = new DateTime(1985, 8, 30),
                Address = "789 Oak St",
                PhoneNumbers = new List<string> { "555-555-3434", "555-555-3435" },
                Email = "[email protected]"
            }
        };

        public IEnumerable<Customer> Get()
        {
            return Customers;
        }

        public Customer Get(int id)
        {
            return Customers.SingleOrDefault(c => c.Id == id);
        }

        public void Post([FromBody] Customer customer)
        {
            Customers.Add(customer);
        }

        public void Put(int id, [FromBody] Customer customer)
        {
            var existingCustomer = Customers.SingleOrDefault(c => c.Id == id);
            if (existingCustomer != null)
            {
                existingCustomer.Name = customer.Name;
                existingCustomer.BirthDate = customer.BirthDate;
                existingCustomer.Address = customer.Address;
                existingCustomer.PhoneNumbers = customer.PhoneNumbers;
                existingCustomer.Email = customer.Email;
            }
        }

        public void Delete(int id)
        {
            Customers.RemoveAll(c => c.Id == id);
        }
    }

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public string Address { get; set; }
        public List<string> PhoneNumbers { get; set; }
        public string Email { get; set; }
    }
}

Change Address to an object containing the properties Address, Address2, City, State, Zipcode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MyAPI
{
    public class CustomersController : ApiController
    {
        private static readonly List<Customer> Customers = new List<Customer>
        {
            new Customer
            {
                Id = 1,
                Name = "John Doe",
                BirthDate = new DateTime(1990, 1, 1),
                Address = new Address
                {
                    Address1 = "123 Main St",
                    Address2 = "Apt 101",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001"
                },
                PhoneNumbers = new List<string> { "555-555-1212", "555-555-1213" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 2,
                Name = "Jane Doe",
                BirthDate = new DateTime(1995, 5, 15),
                Address = new Address
                {
                    Address1 = "456 Park Ave",
                    Address2 = "Suite 202",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001"
                },
                PhoneNumbers = new List<string> { "555-555-2121", "555-555-2122" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 3,
                Name = "Robert Smith",
                BirthDate = new DateTime(1985, 8, 30),
                Address = new Address
                {
                    Address1 = "789 Oak St",
                    Address2 = "",
                    City = "Chicago",
                    State = "IL",
                    ZipCode = "60007"
                },
                PhoneNumbers = new List<string> { "555-555-3434", "555-555-3435" },
                Email = "[email protected]"
            }
        };

        public IEnumerable<Customer> Get()
        {
            return Customers;
        }

        public Customer Get(int id)
        {
            return Customers.SingleOrDefault(c => c.Id == id);
        }

        public void Post([FromBody] Customer customer)
        {
            Customers.Add(customer);
        }

        public void Put(int id, [FromBody] Customer customer)
        {
            var existingCustomer = Customers.SingleOrDefault(c => c.Id == id);
            if (existingCustomer != null)
            {
                existingCustomer.Name = customer.Name;
                existingCustomer.BirthDate = customer.BirthDate;
                existingCustomer.Address = customer.Address;
                existingCustomer.PhoneNumbers = customer.PhoneNumbers;
                existingCustomer.Email = customer.Email;
            }
        }

        public void Delete(int id)
        {
            Customers.RemoveAll(c => c.Id == id);
        }
    }

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public Address Address { get; set; }
        public List<string> PhoneNumbers { get; set; }
        public string Email { get; set; }
    }

    public class Address
    {
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
    }
}

Add Country to the address, but make it an enum of all countries

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MyAPI
{
    public class CustomersController : ApiController
    {
        private static readonly List<Customer> Customers = new List<Customer>
        {
            new Customer
            {
                Id = 1,
                Name = "John Doe",
                BirthDate = new DateTime(1990, 1, 1),
                Address = new Address
                {
                    Address1 = "123 Main St",
                    Address2 = "Apt 101",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001",
                    Country = Country.UnitedStates
                },
                PhoneNumbers = new List<string> { "555-555-1212", "555-555-1213" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 2,
                Name = "Jane Doe",
                BirthDate = new DateTime(1995, 5, 15),
                Address = new Address
                {
                    Address1 = "456 Park Ave",
                    Address2 = "Suite 202",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001",
                    Country = Country.UnitedStates
                },
                PhoneNumbers = new List<string> { "555-555-2121", "555-555-2122" },
                Email = "[email protected]"
            }
        }

        public Customer Get(int id)
        {
            return Customers.SingleOrDefault(c => c.Id == id);
        }

        public void Post([FromBody] Customer customer)
        {
            Customers.Add(customer);
        }

        public void Put(int id, [FromBody] Customer customer)
        {
            var existingCustomer = Customers.SingleOrDefault(c => c.Id == id);
            if (existingCustomer != null)
            {
                existingCustomer.Name = customer.Name;
                existingCustomer.BirthDate = customer.BirthDate;
                existingCustomer.Address = customer.Address;
                existingCustomer.PhoneNumbers = customer.PhoneNumbers;
                existingCustomer.Email = customer.Email;
            }
        }

        public void Delete(int id)
        {
            Customers.RemoveAll(c => c.Id == id);
        }
    }

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public Address Address { get; set; }
        public List<string> PhoneNumbers { get; set; }
        public string Email { get; set; }
    }

    public class Address
    {
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public Country Country { get; set; }
    }

    public enum Country
    {
        UnitedStates,
        Canada,
        Mexico,
        Brazil,
        Argentina,
        Colombia,
        Peru,
        Chile

        // Additional countries omitted for brevity
    }
}

Add validation to make the country, name and email required

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Http;

namespace MyAPI
{
    public class CustomersController : ApiController
    {
        private static readonly List<Customer> Customers = new List<Customer>
        {
            new Customer
            {
                Id = 1,
                Name = "John Doe",
                BirthDate = new DateTime(1990, 1, 1),
                Address = new Address
                {
                    Address1 = "123 Main St",
                    Address2 = "Apt 101",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001",
                    Country = Country.UnitedStates
                },
                PhoneNumbers = new List<string> { "555-555-1212", "555-555-1213" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 2,
                Name = "Jane Doe",
                BirthDate = new DateTime(1995, 5, 15),
                Address = new Address
                {
                    Address1 = "456 Park Ave",
                    Address2 = "Suite 202",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001",
                    Country = Country.UnitedStates
                },
                PhoneNumbers = new List<string> { "555-555-2121", "555-555-2122" },
                Email = "[email protected]"
            },
            new Customer
            {
                Id = 3,
                Name = "Robert Smith",
                BirthDate = new DateTime(1985, 8, 30),
                Address = new Address
                {
                    Address1 = "789 Oak St",
                    Address2 = "",
                    City = "Chicago",
                    State = "IL",
                    ZipCode = "60007",
                    Country = Country.UnitedStates
                },
                PhoneNumbers = new List<string> { "555-555-3434", "555-555-3435" },
                Email = "[email protected]"
            }
        }

        public void Post([FromBody] Customer customer)
        {
            if (ModelState.IsValid)
            {
                Customers.Add(customer);
            }
        }

        public void Put(int id, [FromBody] Customer customer)
        {
            if (ModelState.IsValid)
            {
                var existingCustomer = Customers.SingleOrDefault(c => c.Id == id);
                if (existingCustomer != null)
                {
                    existingCustomer.Name = customer.Name;
                    existingCustomer.BirthDate = customer.BirthDate;
                    existingCustomer.Address = customer.Address;
                    existingCustomer.PhoneNumbers = customer.PhoneNumbers;
                    existingCustomer.Email = customer.Email;
                }
            }
        }

        public void Delete(int id)
        {
            Customers.RemoveAll(c => c.Id == id);
        }
    }

    public class Customer
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        [Required]
        public Address Address { get; set; }
        public List<string> PhoneNumbers { get; set; }
        [Required]
        [EmailAddress]
        public string Email { get; set; }
    }

    public class Address
    {
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        [Required]
        public Country Country { get; set; }
    }

    public enum Country
    {
        UnitedStates,
        Canada,
        Mexico,
        Brazil,
        Argentina,
        Colombia,
        Peru,
        Chile
        // Additional countries omitted for brevity
    }
}

In this updated version of the code, the Customer and Address classes include several [Required] attributes, which indicate that the Name, Address, and Email properties are required and must be non-null when creating or updating a customer. Additionally, the Email property includes the [EmailAddress] attribute, which indicates that it must be a valid email address.

The Post and Put methods check the ModelState to ensure that all required properties are present and valid before adding or updating a customer. If any of the required properties are missing or invalid, the

Write a customers REST API in C# where the customer has the properties Id, Name, Birth Date, Phone numbers, email, an Address object with Address1, address2, city, state, zipcode and a country enum, and add validation to the api

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace CustomerAPI
{
    public class Customer
    {
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public DateTime BirthDate { get; set; }

        [Required]
        public List<string> PhoneNumbers { get; set; }

        [Required]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        public Address Address { get; set; }
    }

    public class Address
    {
        [Required]
        public string Address1 { get; set; }

        public string Address2 { get; set; }

        [Required]
        public string City { get; set; }

        [Required]
        public string State { get; set; }

        [Required]
        [RegularExpression(@"^\d{5}(?:[-\s]\d{4})?$")]
        public string ZipCode { get; set; }

        [Required]
        public Country Country { get; set; }
    }

    public enum Country
    {
        USA,
        Canada,
        Mexico,
        Other
    }
}

This example uses the [Required] attribute to mark properties that must have a value, the [EmailAddress] attribute to validate that a string is a valid email address, and the [RegularExpression] attribute to validate that a string is a valid zip code.

You can add additional validation logic as needed in the setters of the properties or in a separate method. For example, you could add a method to validate the customer’s age and ensure that they are over 18 years old.

Write the REST Controller for managing the customer resource and save it in RavenDB

using System.Linq;
using System.Web.Http;
using CustomerAPI.Models;
using Raven.Client.Documents;

namespace CustomerAPI.Controllers
{
    public class CustomerController : ApiController
    {
        private readonly IDocumentStore store;

        public CustomerController()
        {
            store = new DocumentStore
            {
                Urls = new[] { "http://localhost:8080" },
                Database = "Customers"
            };

            store.Initialize();
        }

        // GET api/customer
        public IEnumerable<Customer> Get()
        {
            using (var session = store.OpenSession())
            {
                return session.Query<Customer>().ToList();
            }
        }

        // GET api/customer/5
        public Customer Get(int id)
        {
            using (var session = store.OpenSession())
            {
                return session.Load<Customer>(id);
            }
        }

        // POST api/customer
        public void Post([FromBody]Customer customer)
        {
            using (var session = store.OpenSession())
            {
                session.Store(customer);
                session.SaveChanges();
            }
        }

        // PUT api/customer/5
        public void Put(int id, [FromBody]Customer customer)
        {
            using (var session = store.OpenSession())
            {
                var existingCustomer = session.Load<Customer>(id);
                existingCustomer.Name = customer.Name;
                existingCustomer.BirthDate = customer.BirthDate;
                existingCustomer.PhoneNumbers = customer.PhoneNumbers;
                existingCustomer.Email = customer.Email;
                existingCustomer.Address = customer.Address;

                session.SaveChanges();
            }
        }

        // DELETE api/customer/5
        public void Delete(int id)
        {
            using (var session = store.OpenSession())
            {
                var customer = session.Load<Customer>(id);
                session.Delete(customer);
                session.SaveChanges();
            }
        }
    }
}

This controller defines the following endpoints for managing customer resources:

GET api/customer: Returns a list of all customers.
GET api/customer/{id}: Returns the customer with the specified ID.
POST api/customer: Creates a new customer. The customer data should be provided in the request body.
PUT api/customer/{id}: Updates the customer with the specified ID. The updated customer data should be provided in the request body.
DELETE api/customer/{id}: Deletes the customer with the specified ID.

This example uses the RavenDB document store to save and retrieve customer data. The store is initialized with the URL of the RavenDB server and the name of the database to use. The controller’s actions then use the store to open a session and perform the requested operations on the customer data.

Note that this is just one possible implementation of a REST controller for managing customer resources, and there are many other ways to implement such a controller depending on your specific requirements and preferences.

Add data validation

To validate the model, you can use the Validator.TryValidateObject method in the controller’s actions before saving or updating the customer data. For example:

// POST api/customer
public void Post([FromBody]Customer customer)
{
    var validationContext = new ValidationContext(customer);
    var validationResults = new List<ValidationResult>();

    if (!Validator.TryValidateObject(customer, validationContext, validationResults))
    {
        // Handle validation errors
    }
    else
    {
        using (var session = store.OpenSession())
        {
            session.Store(customer);
            session.SaveChanges();
        }
    }
}

This example uses the Validator.TryValidateObject method to validate the customer model before saving it to the database. If the model is not valid, the method returns false and the validationResults list contains the validation errors. You can then handle the validation errors as needed, for example by returning an appropriate HTTP response to the client.

Note that this is just one possible approach to adding data validation to the customer REST API.

Make it async

To make the customer REST API asynchronous, you can use the async and await keywords to mark methods that contain asynchronous operations, and the Task class to represent the asynchronous operation.

Here is an example of how you could modify the customer controller to make it asynchronous:

using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using CustomerAPI.Models;
using Raven.Client.Documents;

namespace CustomerAPI.Controllers
{
    public class CustomerController : ApiController
    {
        private readonly IDocumentStore store;

        public CustomerController()
        {
            store = new DocumentStore
            {
                Urls = new[] { "http://localhost:8080" },
                Database = "Customers"
            };

            store.Initialize();
        }

        // GET api/customer
        public async Task<IEnumerable<Customer>> Get()
        {
            using (var session = store.OpenAsyncSession())
            {
                return await session.Query<Customer>().ToListAsync();
            }
        }

        // GET api/customer/5
        public async Task<Customer> Get(int id)
        {
            using (var session = store.OpenAsyncSession())
            {
                return await session.LoadAsync<Customer>(id);
            }
        }

        // POST api/customer
        public async Task Post([FromBody]Customer customer)
        {
            var validationContext = new ValidationContext(customer);
            var validationResults = new List<ValidationResult>();

            if (!Validator.TryValidateObject(customer, validationContext, validationResults))
            {
                // Handle validation errors
            }
            else
            {
                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(customer);
                    await session.SaveChangesAsync();
                }
            }
        }

        // PUT api/customer/5
        public async Task Put(int id, [FromBody]Customer customer)
        {
            var validationContext = new ValidationContext(customer);
            var validationResults = new List<ValidationResult>();

            if (!Validator.TryValidateObject(customer, validationContext, validationResults))
            {
                // Handle validation errors
            }
            else
            {
                using (var session = store.OpenAsyncSession())
                {
                    var existingCustomer = await session.LoadAsync<Customer>(id);
                    existingCustomer.Name = customer.Name;
                    existingCustomer.BirthDate = customer.BirthDate;
                    existingCustomer.PhoneNumbers = customer.PhoneNumbers;
                    existingCustomer.Email = customer.Email;
                    existingCustomer.Address = customer.Address;

                    await session.SaveChangesAsync();
                }
            }
        }

        // DELETE api/customer/5
        public async Task Delete(int id)
        {
            using (var session = store.OpenAsyncSession())
            {
                var customer = await session.LoadAsync<Customer>(id);
                session.Delete(customer);
                await session.SaveChangesAsync();
            }
        }
    }
}

This example uses the async and await keywords


Tags

AIideas
Alexandru Puiu

Alexandru Puiu

Engineer / Security Architect

Systems Engineering advocate, Software Engineer, Security Architect / Researcher, SQL/NoSQL DBA, and Certified Scrum Master with a passion for Distributed Systems, AI and IoT..

Expertise

.NET
RavenDB
Kubernetes

Social Media

githubtwitterwebsite

Related Posts

State Machine Capabilities
Representing State Machine Capabilities using neo4j / graph databases
February 08, 2019
8 min
Observability
DevOps
Observability using Elasticsearch and Neo4j
December 05, 2019
7 min

Subscribe To My Newsletter

I'll only send worthwhile content I think you'll want, less than once a month, and promise to never spam or sell your information!
© 2023, All Rights Reserved.

Quick Links

Get In TouchAbout Me

Social Media