What is an entity in Akka-Http? - scala

I am new to akka-http and building a basic server-client application in scala. The examples I looked at has the object "entity". Can someone please explain the concept underlying and why is it used and how is it useful?
post {
path("insert") {
entity(as[Student]) {
obj => complete {
insertingstudent(obj)
s"got obj with name ${obj.getName()}"
}
}
Thanks

Can someone please explain the concept underlying and why is it used
and how is it useful?
entity is of type HttpEntity. From the comments of the code:
Models the entity (aka "body" or "content") of an HTTP message.
It is an abstraction over the content of the HTTP request. Many times, when one sends an HTTP request, they provide a payload inside the body of the request. This body can be in many format, popular ones are JSON and XML.
When you write:
entity(as[Student])
You are attempting to unmarhsall, or deserialize, the body of the request into a data structure of your liking. That means that your obj field in the proceeding function will be of type Student.

Related

Efficient JSON-toJSON transformations with spray-json

I have a scenario similar to this: an Akka HTTP service calls another service and performs some transformations on its JSON response. Let's say it replaces "http" with "https" on every "link" attribute's value.
Right now the implementation is something like:
def route: Route =
callToAnotherService(request) { eventualJsonResponse =>
complete(
eventualJsonResponse.flatMap(
(jsonResponse: HttpResponse) => {
Unmarshal(jsonResponse.entity.withContentType(MediaTypes.`application/json`))
.to[JsValue]
.map(replaceHttpInLinks)
.flatMap(Marshal(_).to[ResponseEntity])
.map(responseEntity => jsonResponse.copy(entity = responseEntity)))
}
)
)
}
The transformation method has the following signature:
def replaceHttpInLinks(jsValue: JsValue): JsValue = {
// Recursively find "link" attributes and replace protocol
}
As you can see, the called service's JSON response is unmarshalled into a JsValue object and then this object is used to perform the changes.
That response can be huge, and I'm concerned about both performance and memory consumption.
I was looking for a way of making those changes without unmarshalling the whole JSON document, and hopefully without introducing foreign libraries (Play JSON or others). I was thinking of something event based, along the lines of the old SAX API for XML.
Does anyone come up with any idea to achieve it?
I think that with Spray is more complicated because it will try to build the JsValue from the body of the HTTPRequest. My suggestion is to use Circe and use HCursor to unmarshall manually. Take a look to some exampl here.
You can integrate circe with Akka: https://github.com/hseeberger/akka-http-json

Multiple payloads in MVC core rest api

I am developing a rest api on .Net core 2.2 following MVC pattern.
I have a controller with a post method like this...
// POST: api/Todo
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(string param, [FromBody] TodoItem item)
{
// some work...
return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
}
And it works fine.
The customer asked to have an api on the same route, but the Json body could have 2 different structures, bearing the same data on different schemas.
I considered using
PostTodoItem(string param, [FromBody] Object item)
{
// TryCast item to one of the possible POCO classes then work with the correct one.
}
Do you know a better way, maybe with some advanced routing and filtering option?
This is not really possible nor desirable. Pretty much the core tenant of REST is a URI uniquely represents a particular resource. If you've got a URI like POST /todo, then the post body should be a "todo" and it should create a new "todo" based on that. Here, that is a TodoItem, so that is all that should ever be posted.
REST aside, this just won't work. When your action is activated, the modelbinder attempts to bind the post body to the param(s) that the action accepts. It basically just news up whatever type the param is, and then attempts to find something from the post body to bind to the various properties on that type. This is an intentionally simplistic description of what's happening; the important part is that the type of the param informs how the post body is bound. If you bind to an object (which has no members) or even a base type, then the only members of the post body that will be bound are those that are present on that type, not derived types thereof. Anything that cannot be bound is discarded.
Long and short, you need a unique route for each type of thing you're working with. Under the hood, you can share or otherwise reuse code by factoring out common functionality into private methods, employing inheritance, etc., but you need a distinct action and route to handle each case.

Sending an Object as a Parameter to GET Request: PlayFramework

I have a class Caller:
class Caller{
String caller;
String callTo;
String x, y , z;
}
Now, I want to send a GET request:
localhost:9000/api/v1/call
But I want to send and Object "obj" of Type Caller as the parameters to this Request, so that my receiving api will be simply able to get everything it needs from the Caller object.
I saw a lot of material in the official PLay Documentation; all talking about Templates. I dont think I am looking in the right direction.
Can someone please help me proceed in the right direction?
Any example on how to send my "Caller" object as Parameter to GET REQUEST?
PS: I am using Play Framework 2.3.X in Java.

Post array of object to WCF Rest service using JSON?

Need to send a complex object having nested IList from Iphone in JSON format to WCF REST service. The Complex Object is defined as following:
public class BatchData
{
long BatchID;
List<Account> Accounts;
List<Contacts> Contacts;
}
Please let me know the Client side (IPhone) syntax to create the required JSON request and also the server side POST method implementation to handle such scenario ?
Thanks in advance.
For the server side: define an operation contract which takes an array of that type. Search for examples on WCF Rest services (you'll need to use the [WebInvoke] attribute to define your operation) and you'll find how to do it.
For the client side: you can send the request using the NSURLRequest class. And to create the appropriate JSON, you can look at the NSJSONSerialization class, which will help you to convert between arrays (NSArray) and dictionaries (NSDictionary) and the JSON you need to send to the service.

In JAX RS, differences between returning Response and Bean or Collection of Beans (DTO)

I am working on building a REST api. My question is, when using Jersey, what are the differences between my services building and returning a Response object or returning the the bean or collection. I am only concerned with successful calls, I am throwing appropriate exceptions for errors and exceptional situations.
Here is a example:
#Produces(MediaType.APPLICATION_JSON)
public Response search(FooBean foo){
List<FooBean> results = bar.search(foo);
return Response.ok(results).build();
}
vs.
#Produces(MediaType.APPLICATION_JSON)
public List<FooBean> search(FooBean foo){
List<FooBean> results = bar.search(foo);
return results;
}
I've seen both examples used, and I'd prefer the second scenario, just to make it easier to recognize the service method. I've examined the responses to both of these methods and they appear to be identical.
Thoughts?
The differences are explained in the JAX-RS specification:
3.3.3 Return Type
Resource methods MAY return void, Response, GenericEntity, or another Java type, these return types are mapped to a response entity body as follows:
void
Results in an empty entity body with a 204 status code.
Response
Results in an entity body mapped from the entity property of the Response with the status code specified by the status property of the Response. A null return value results in a 204 status code. If the status property of the Response is not set: a 200 status code is used for a non-null entity property and a 204 status code is used if the entity property is null.
GenericEntity
Results in an entity body mapped from the Entity property of the GenericEntity. If the return value is not null a 200 status code is used, a null return value results in a 204 status code.
Other
Results in an entity body mapped from the class of the returned instance. If the return value is not null a 200 status code is used, a null return value results in a 204 status code.
Methods that need to provide additional metadata with a response should return an instance of Response, the ResponseBuilder class provides a convenient way to create a Response instance using a builder pattern.
'Regular' beans are mapped over in pretty much the same way as Response is, with the exception that a Response allows you to set additional metadata (response headers, specialized status, specialized content type, etc). As far as which one to use, thats entirely up to you too decide - Response gives you more flexibility, but regular beans are more 'self-documenting'.
There is no diference if you want to return always the response 200 - OK , catching and manipulate all the exceptions that may occur before of after your method return the result, with interceptions or WebApplicationException. So, both of these methods will result the same responses.
The only diference is at specific scenarios, like returning null objects, or creating object, like this example:
#POST
#Consumes("application/json")
public Response post(String content) {
URI createdUri = ...
Object createdContent = create(content);
return Response.created(createdUri).entity(createdContent).build();
}
In this case the return will be 201 - CREATED (With the URI to access the created object)
So, the following method:
#POST
#Consumes("application/json")
public Object post(String content) {
URI createdUri = ...
Object createdContent = create(content);
return createdContent;
}
... will return a response 200 - OK
If you don't care about which response status your client will receive, you can use any of declarations without problem.
Source: Jersey.
My personal of view, if response contains DTO (Bean/Collection of beans), then rest service always must return DTO, but not Response object.
The motivation: early or late, you will be asked to make a usage of rest service easier for clients, by providing rest client api. Usually, you have to extract rest interfaces for it, and implement them with your rest services. These rest interfaces are used by clients of your rest client.
And from a client point of view there is a huge difference between processing DTO and plain Response. In case Response is used, your client is forced:
Check response code explicitely to process successfull response
Handle errors, by checking codes explicitly
Convert body of your response into DTO by himself.
Which means handling Response is very similar to returning error codes in methods, which is considered as a very bad practice. In order to handle errors in one place, exceptions are used (I'm not talking about FP ways of handle errors, which is the best).
So what may you do:
In case a request is processed successfully, convert in your rest service data into DTO/Bean and return it.
In case if validation failed, or something went wrong, throw an exception in your rest service. Perhaps a default exception mapper is not good for you, so, you'll have to implement your own exception mapper.
So if to think in advance, you should return DTO.
One use-case, when plain Response should be returned - when you export file, for instance. It seems JAX RS does not allow to return InputStream object. Not sure, it has to be checked.
The other use case, was pointed by #Perception, but it is more an exception, than a rule:
Methods that need to provide additional metadata with a response
should return an instance of Response, the ResponseBuilder class
provides a convenient way to create a Response instance using a
builder pattern.
Note: it is a general question for JAX RS, does not depend on exact implementation, like Resteasy or Jersey