Let say I have a API that sends simple messages to users. To send it I would use something like:
POST {
Content: "Message here",
To: "[email protected]"
} api/messages
Now I want to read all sent messages but with user who send it (I had identity in cookie) and send time (assigned automatically). Again it seems to be simple:
GET api/messages
and I will get:
[{
Content: "Message here",
To: "[email protected]",
From: "user1",
Time: "0001-01-01T00:00:00"
}]
From API controller side I will have two methods:
public class MessagesController : ApiController
{
[HttpPost, Route("Messages")]
public HttpResponseMessage Post([FromBody] Message message)
{
messageRepository.Create(message);
return Request.CreateResponse(HttpStatusCode.Created, "Message was send.");
}
[HttpGet, Route("Messages")]
public HttpResponseMessage Get()
{
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(JsonConvert.SerializeObject(messageRepository.GetMessages()))
};
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return response;
}
}
My problem is that the object what is send is different from object what i get. So I think I can't use same Message class. Why should I do then:
Think of the objects being sent over the wire as DTOs (Data Transfer Objects). It is usually advised that you should only send what is necessary over the wire.
So your client should only construct what the api expects. If From
and Time
is data that the client does not need to provide then it shouldn't.
public class PostMessageDto {
public string Content { get; set; }
public string To {get; set; }
}
From a security perspective you don't want to leak more information than is necessary for the client. If your entities are exposing more information than you want exposed you should create a model to pass only the details you want sent to the client.
public class MessagesController : ApiController {
//POST api/messages
[HttpPost, Route("Messages")]
public HttpResponseMessage Post([FromBody] PostMessageDto message) {
var entity = new Message {
Content = message.Content,
To = message.To
};
messageRepository.Create(entity);
return Request.CreateResponse(HttpStatusCode.Created, "Message was send.");
}
//GET api/messages
[HttpGet, Route("Messages")]
public HttpResponseMessage Get() {
var entities = messageRepository.GetMessages();
//..you can put code here that creates the data you want returned.
var responseData= entities.Select(x => new {
Content = x.Content,
To = x.To,
From = x.From,
Time = x.Time
});
var response = Request.CreateResponse(HttpStatusCode.OK, responseData);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return response;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With