-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update RESTful API README * Add Message-API source code * Fix a few typos * Fix typo * Tidied up project for PR * Switched for loop to LINQ query * Fixed bad link Co-authored-by: Rodger Gu <[email protected]>
- Loading branch information
Showing
22 changed files
with
968 additions
and
23 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
3. RESTful-API workshop/Message-API/.idea/.idea.MessageAPI.dir/.idea/.gitignore
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
3. RESTful-API workshop/Message-API/.idea/.idea.MessageAPI.dir/.idea/.name
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
3. RESTful-API workshop/Message-API/.idea/.idea.MessageAPI.dir/.idea/encodings.xml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
8 changes: 8 additions & 0 deletions
8
3. RESTful-API workshop/Message-API/.idea/.idea.MessageAPI.dir/.idea/indexLayout.xml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
6 changes: 6 additions & 0 deletions
6
3. RESTful-API workshop/Message-API/.idea/.idea.MessageAPI.dir/.idea/vcs.xml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
120 changes: 120 additions & 0 deletions
120
3. RESTful-API workshop/Message-API/Controllers/MessageItemController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#nullable disable | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.EntityFrameworkCore; | ||
using MessageAPI.Models; | ||
using MessageAPI.Models.DTO; | ||
|
||
namespace MessageAPI.Controllers; | ||
|
||
[Route("api/message")] | ||
[ApiController] | ||
public class MessageItemController : ControllerBase | ||
{ | ||
private readonly MessageContext _context; | ||
private readonly ILogger<MessageItemController> _logger; | ||
|
||
public MessageItemController(MessageContext context, ILogger<MessageItemController> logger) | ||
{ | ||
_context = context ?? throw new ArgumentNullException(nameof(context)); | ||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
/// <summary> | ||
/// Gets all messages | ||
/// </summary> | ||
/// <returns>A response with the list of messages</returns> | ||
[HttpGet] | ||
public async Task<ActionResult<IEnumerable<MessageItemDTO>>> GetMessageItems() | ||
{ | ||
var messageItems = await _context.MessageItems.ToListAsync(); | ||
return messageItems.Select(messageItem => new MessageItemDTO | ||
{ Id = messageItem.Id, MainMessage = messageItem.MainMessage }).ToArray(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets a single message | ||
/// </summary> | ||
/// <param name="id">The ID of the message to return</param> | ||
/// <returns>The message with that ID, or a 404 response if the message does not exist</returns> | ||
[HttpGet("{id}")] | ||
public async Task<ActionResult<MessageItemDTO>> GetMessageItem(int id) | ||
{ | ||
var messageItem = await _context.MessageItems.FindAsync(id); | ||
|
||
if (messageItem == null) | ||
{ | ||
return NotFound(); | ||
} | ||
|
||
// Strip out the password | ||
var messageItemDto = new MessageItemDTO { Id = messageItem.Id, MainMessage = messageItem.MainMessage }; | ||
|
||
return messageItemDto; | ||
} | ||
|
||
/// <summary> | ||
/// Updates the message if it exists | ||
/// </summary> | ||
/// <param name="id">The message to update</param> | ||
/// <param name="messageUpdateDto">The request body</param> | ||
/// <param name="password">The password associated with the message</param> | ||
/// <returns>A 404 response if the message doesn't exist, or a 204 if it has been updated</returns> | ||
[HttpPatch("{id}")] | ||
[ProducesResponseType(StatusCodes.Status204NoContent)] | ||
public async Task<IActionResult> PatchMessageItem(int id, MessageUpdateDTO messageUpdateDto, | ||
[FromHeader(Name = "password")] string password) | ||
{ | ||
_logger.LogInformation("Password: {Password}", password); | ||
|
||
// If the password doesn't match the old message password, return bad request. | ||
var oldMessageItem = await _context.MessageItems.FindAsync(id); | ||
if (oldMessageItem is null) return BadRequest(); | ||
|
||
if (password != oldMessageItem.Password) | ||
{ | ||
return Unauthorized(); | ||
} | ||
|
||
oldMessageItem.MainMessage = messageUpdateDto.MainMessage; | ||
await _context.SaveChangesAsync(); | ||
|
||
return NoContent(); | ||
} | ||
|
||
/// <summary> | ||
/// Creates a new message | ||
/// </summary> | ||
/// <param name="messageItem">The new message item to create</param> | ||
/// <returns>a success code if the message has been created</returns> | ||
[HttpPost] | ||
[ProducesResponseType(StatusCodes.Status201Created)] | ||
public async Task<ActionResult<MessageItem>> PostMessageItem(MessageItem messageItem) | ||
{ | ||
_context.MessageItems.Add(messageItem); | ||
await _context.SaveChangesAsync(); | ||
|
||
return CreatedAtAction(nameof(GetMessageItem), new { id = messageItem.Id }, messageItem); | ||
} | ||
|
||
/// <summary> | ||
/// Deletes a message if it exists | ||
/// </summary> | ||
/// <param name="id">The ID of the message to delete</param> | ||
/// <returns>A 200 OK response</returns> | ||
[HttpDelete("{id}")] | ||
public async Task<IActionResult> DeleteMessageItem(int id) | ||
{ | ||
var messageItem = await _context.MessageItems.FindAsync(id); | ||
if (messageItem is null) | ||
{ | ||
// if we return not found, people who shouldn't know a message exists can find | ||
// a message's existence from the response type | ||
return Ok(); | ||
} | ||
|
||
_context.MessageItems.Remove(messageItem); | ||
await _context.SaveChangesAsync(); | ||
|
||
return Ok(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.4"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.4" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.4" /> | ||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.3" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> | ||
</ItemGroup> | ||
|
||
</Project> |
7 changes: 7 additions & 0 deletions
7
3. RESTful-API workshop/Message-API/Models/DTO/MessageItemDTO.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace MessageAPI.Models.DTO; | ||
|
||
public class MessageItemDTO | ||
{ | ||
public int Id { get; set; } | ||
public string? MainMessage { get; set; } | ||
} |
6 changes: 6 additions & 0 deletions
6
3. RESTful-API workshop/Message-API/Models/DTO/MessageUpdateDTO.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace MessageAPI.Models.DTO; | ||
|
||
public class MessageUpdateDTO | ||
{ | ||
public string? MainMessage { get; set; } | ||
} |
13 changes: 13 additions & 0 deletions
13
3. RESTful-API workshop/Message-API/Models/MessageContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace MessageAPI.Models; | ||
|
||
public class MessageContext : DbContext | ||
{ | ||
public MessageContext(DbContextOptions<MessageContext> options) | ||
: base(options) | ||
{ | ||
} | ||
|
||
public DbSet<MessageItem> MessageItems { get; set; } = default!; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace MessageAPI.Models; | ||
|
||
public class MessageItem | ||
{ | ||
public int Id { get; set; } | ||
public string? MainMessage { get; set; } | ||
public string? Password { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
using MessageAPI.Models; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
// Add services to the container. | ||
|
||
builder.Services.AddControllers(); | ||
builder.Services.AddDbContext<MessageContext>(opt => | ||
opt.UseInMemoryDatabase("Messages")); | ||
builder.Services.AddSwaggerGen(c => | ||
{ | ||
c.SwaggerDoc("v1", new() { Title = "MessageAPI", Version = "v1" }); | ||
}); | ||
builder.Services.AddLogging(); | ||
|
||
var app = builder.Build(); | ||
|
||
// Configure the HTTP request pipeline. | ||
if (builder.Environment.IsDevelopment()) | ||
{ | ||
// app.UseDeveloperExceptionPage(); | ||
} | ||
|
||
app.UseSwagger(); | ||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MessageAPI v1")); | ||
app.UseHttpsRedirection(); | ||
|
||
app.UseAuthorization(); | ||
app.UseHttpLogging(); | ||
|
||
app.MapControllers(); | ||
|
||
app.Run(); |
31 changes: 31 additions & 0 deletions
31
3. RESTful-API workshop/Message-API/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/launchsettings.json", | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:39533", | ||
"sslPort": 44361 | ||
} | ||
}, | ||
"profiles": { | ||
"MessageAPI": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"applicationUrl": "https://localhost:7298;http://localhost:5250", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# How to run | ||
Ensure that you have [.Net 6.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) installed on your computer, open a terminal in this folder and run `dotnet restore` then `dotnet run` | ||
|
||
> Understanding the API source code is not required for this module. However, this may help you with phase 2 and 3 :) |
8 changes: 8 additions & 0 deletions
8
3. RESTful-API workshop/Message-API/appsettings.Development.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
}, | ||
"AllowedHosts": "*" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,42 @@ | ||
# MSA 2022 RESTful API workshop | ||
# RESTful API Workshop | ||
|
||
Welcome to the RESTful API Workshop. The goal for this workshop is for you to get familar with RESTful API concepts and have some hands on experience with interactive with an API. You will perform CRUD operations, that is, Create, Read, Update and Delete operations on an API that we have created. You may use any tools to interact with the API, such as JavaScript, Python and Postman. | ||
Welcome to the RESTful API Workshop. The goal for this workshop is for you to get familiar with RESTful API concepts and have some hands on experience with interactive with an API. You will perform CRUD operations, that is, Create, Read, Update and Delete operations on an API that we have created. You may use any tools to interact with the API, such as JavaScript, Python and Postman. | ||
|
||
- Pre-requisite: https://docs.microsoft.com/en-us/learn/modules/build-web-api-minimal-api/ | ||
|
||
If you are not sure what tool to use to interact with the API, we recommend you to use [Postman](https://www.postman.com/), it is a GUI API platform for building and using APIs. | ||
|
||
## Assignment | ||
> Alternatively, you can also use the swagger UI built into the web API. | ||
### Exercise 1: READ | ||
> You can find the UI by visiting: [https://2022-nsmsa-phase-1-api.azurewebsites.net/swagger](https://2022-nsmsa-phase-1-api.azurewebsites.net/swagger). However, we recommend that you don't use this UI unless you are stuck. | ||
Get a list of messages that other people have created in the API. The link to the API endpoint is: https://www.2022-nsmsa-phase-1-api.azurewebsites.net/api/message | ||
## Assignment | ||
### Exercise 1: READ | ||
|
||
> Hint: For this exercise, you will need to use the HTTP GET Request. | ||
Get a list of messages that other people have created in the API. The link to the API endpoint is: https://2022-nsmsa-phase-1-api.azurewebsites.net/api/message | ||
> Hint: For this exercise, you will need to use the HTTP GET Request. | ||
### Exercise 2: CREATE | ||
|
||
Now that you have retrieved information from the API, let's try to do add something to the database via the API. Again, use the same endpoint, but a different HTTP method, post a message to the API: https://www.2022-nsmsa-phase-1-api.azurewebsites.net/api/message | ||
The API takes in form-data with three key-value pair: Nickname, Message and Password. The nickname and message will be publicly displayed, whereas password will be used to authenticate you when you want to update or delete your message. Please do not put in the password that you have used somewhere else for this exercise. | ||
Now that you have retrieved information from the API, let's try to do add something to the database via the API. Again, use the same endpoint, but a different HTTP method, post a message to the API: https://2022-nsmsa-phase-1-api.azurewebsites.net/api/message | ||
|
||
> Hint: You will need to use an HTTP POST request. | ||
The API takes in [json](https://json.org/example.html) formatted data with three key-value pair: "Nickname", "MainMessage" and "Password". The nickname and message will be publicly displayed, whereas password will be used to authenticate you when you want to update or delete your message. Please do not put in the password that you have used somewhere else for this exercise. | ||
> Hint: You will need to use an HTTP POST request. | ||
> Hint 2: You may also need to set your a HTTP header: "Content-Type" with the value of "application/json". | ||
After you have received the success message, you may retrieve your information using a GET request, just like you did in exercise 1. | ||
After you have received the success message, you may retrieve your information using a GET request, just like you did in exercise 1. | ||
|
||
### Exercise 3: UPDATE | ||
After you confirm that your entry is indeed living in the database. You next task is to update the message to say something else. The endpoint for this is: https://2022-nsmsa-phase-1-api.azurewebsites.net/api/message/MESSAGEID, where "MESSAGEID" is ID of the message you would like to update. In order to prevent unauthorized update by other people, you will need to input your password in the HTTP header. The API endpoint takes in json with one key-value pair: MainMessage (Which is the new message you want to update to). | ||
|
||
After you confirm that your entry is indeed living in the database. You next task is to update the message to say something else. In order to prevent unauthorized update by other people, you will need to input your password in the HTTP header. The API endpoint takes in form-data with two key-value pair: ID (Which you can find by finding your message with the GET request) and message (Which is the new message you want to update to). | ||
|
||
> Hint: You will want to use PATCH request for this exercise. | ||
> Hint: You will want to use PATCH request for this exercise. | ||
### Exercise 4: DELETE | ||
Your last task is to delete an entry from the database. Again, you will need to authenticate by providing your password in the HTTP header. The API endpoint is: https://2022-nsmsa-phase-1-api.azurewebsites.net/api/message/MESSAGEID, where "MESSAGEID" is ID of the message you would like to delete. | ||
|
||
Your last task is to delete an entry from the database. Again, you will need to authenticate by providing your password in the HTTP header. This API endpoint takes in form-data with simply one key-value pair: ID. | ||
|
||
> Hint: You will want to use DELETE request for this exercise. | ||
> Hint: You will want to use DELETE request for this exercise. | ||
Note that your message won't get deleted from the database, as we want other students to see your message! But if you have received a 200 status code as a response, considered the task completed! | ||
|
||
### Stuck somewhere? | ||
Feel free to create a new discussion in our GitHub repository! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.