Validate REST parameter in Quarkus Microprofile - api

The following code is part of a controller in a Quarkus Microprofile API application.
#GET
#Path("/limit/{limit}/offset/{offset}")
#Produces(MediaType.APPLICATION_JSON)
public Response paginatedAccounts(
#Parameter(
description = "Number of records to be returned.",
required = true,
schema = #Schema(type = SchemaType.INTEGER))
#PathParam("limit") int limit,
#Parameter(
description = "The starting number of record, zero based.",
required = true,
schema = #Schema(type = SchemaType.INTEGER))
#PathParam("offset") int offset)
{
return Response
.ok(this.accountService.getPaginatedAccounts(limit, offset))
.build();
}
It returns a paginated list of accounts.
When user calls the API providing a wrong type for "limit" or "offset", ie:
http://[url]/[entity]/limit/zzz/offset/0
she receives "404 - Not Found"
How to validate the parameters "limit" and "offset" so that when user supplies a wrong type (string for int) she receives instead:
"400 - Bad Request"
as it should be?

This is by design (of the JAX-RS spec).
https://docs.oracle.com/cd/E19798-01/821-1841/6nmq2cp1v/index.html mentions it explicitly:
If the URI path template variable cannot be cast to the specified type, the JAX-RS runtime returns an HTTP 400 (“Bad Request”) error to the client. If the #PathParam annotation cannot be cast to the specified type, the JAX-RS runtime returns an HTTP 404 (“Not Found”) error to the client

Related

Locale aware bean validation message interpolation at ExceptionMapper in openliberty

I have a JAX-RS #POST endpoint whose input data has to be #Valid:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response myEndpoint(#javax.validation.Valid MyInputData input) { /*...*/ }
With MyInputData class annotated with many constraints:
#lombok.Data
public class InputData {
#Size(min = 1, max = 3)
private String someString;
/* ... */
}
Beyond that I have an ExceptionMapper<ConstraintViolationException> that transform the Exception into a Collection<String> (basically every single ConstraintViolation transformed to String using its getMesssage() method), then returns a Response.status(Status.BAD_REQUEST).entity(list).build().
Everything is working nicely. Fed an invalid input and I get back a HTTP 400 with a nice array of constraint violations in json format.
So far, so good...
BUT... the messages are in server's locale. Even if HTTP post sends a Accept-language header (and it is correctly detected when getting HttpServletRequest::getLocale).
By the time the ExceptionMapper gets hold of ConstraintViolation every message has already been interpolated, so no chance set the client locale.
Since the validation runs even before the JAX-RS resource (indeed, the JAX-RS resource isn't even called in case of invalid input), this locale aware message interpolator must be configured somewhere else.
Where? Is there already a MessageInterpolator implementation whose operation takes the HttpServletRequest locale into account?

how to evaluate java function using __groovy and assign it as part of Http Request

I have a http request with the following structure.
Http Request :-
"Accounts": [
{
"accountType": "SAVINGS",
"RefNumber": "${RefNumber}",
"accountNo": "${AccNumber}"
}
],
"encryptionKey": "${__groovy(new com.util.EncryptUtil().encrypt(), encryptedValue)}"
The value of encryptionKey is calculated using the mentioned groovy function. The encrypt function takes the Accounts object and calculates the encryptedValue based on the value of RefNumber and accountNo. The value of accountNo comes from the first Http Response API. The value of the RefNumber comes from the second Http Response API. How do I accept the dynamic Accounts object json and calculate the encrypted value in jmeter and how do I check if the function result is being assigned to encryptionKey using jmeter?
First of all you can check your function output using The Function Helper Dialog
Example class I use for demo looks like:
package com.util;
public class EncryptUtil {
public String encrypt() {
return "some encrypted value";
}
}
Second, you can check your request payload using View Results Tree listener
And finally you can check generated ${encryptedValue} variable using Debug Sampler

How do I get the message from an API using Flurl?

I've created an API in .NET Core 2 using C#. It returns an ActionResult with a status code and string message. In another application, I call the API using Flurl. I can get the status code number, but I can't find a way to get the message. How do I get the message or what do I need to change in the API to put the message someway Flurl can get it?
Here's the code for the API. The "message" in this example is "Sorry!".
[HttpPost("{orderID}/SendEmail")]
[Produces("application/json", Type = typeof(string))]
public ActionResult Post(int orderID)
{
return StatusCode(500, "Sorry!");
}
Here's the code in another app calling the API. I can get the status code number (500) using (int)getRespParams.StatusCode and the status code text (InternalError) using getRespParams.StatusCode, but how do I get the "Sorry!" message?
var getRespParams = await $"http://localhost:1234/api/Orders/{orderID}/SendEmail".PostUrlEncodedAsync();
int statusCodeNumber = (int)getRespParams.StatusCode;
PostUrlEncodedAsync returns an HttpResponseMessage object. To get the body as a string, just do this:
var message = await getRespParams.Content.ReadAsStringAsync();
One thing to note is that Flurl throws an exception on non-2XX responses by default. (This is configurable). Often you only care about the status code if the call is unsuccessful, so a typical pattern is to use a try/catch block:
try {
var obj = await url
.PostAsync(...)
.ReceiveJson<MyResponseType>();
}
catch (FlurlHttpException ex) {
var status = ex.Call.HttpStatus;
var message = await ex.GetResponseStringAsync();
}
One advantage here is you can use Flurl's ReceiveJson to get the response body directly in successful cases, and get the error body (which is a different shape) separately in the catch block. That way you're not dealing with deserializing a "raw" HttpResponseMessage at all.

Spring Data Rest Content Type

I am writing unit tests for my application with Spring Data Rest MongoDB. Based on Josh's "Building REST services with Spring" get start guide, I have the following test code:
#Test
public void readSingleAccount() throws Exception {
mockMvc.perform(get("/accounts/"
+ this.account.getId()))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.id", is(this.account.getId())))
.andExpect(jsonPath("$.email", is(this.account.getEmail())))
.andExpect(jsonPath("$.password", is(this.account.getPassword())));
}
And this test fails on the content type.
Content type expected:<application/json;charset=UTF-8> but was: <application/hal+json>
Expected :application/json;charset=UTF-8
Actual :application/hal+json
I don't see MediaType come with HAL. Is the content type defined in another class?
Had the same Problem when not using tomcat (which is configured to return utf-8 using Spring Boot). The solution is to set the accept header in your GET request so the response gets the correct content type:
private MediaType contentType = new MediaType("application", "hal+json", Charset.forName("UTF-8"));
and in your request, do
#Test
public void readSingleAccount() throws Exception {
mockMvc.perform(get("/accounts/"
+ this.account.getId()).**accept(contentType)**)
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.id", is(this.account.getId())))
.andExpect(jsonPath("$.email", is(this.account.getEmail())))
.andExpect(jsonPath("$.password", is(this.account.getPassword())));
}

REST GET api - what to return when resource not found

I am using jersey to create rest api. I have GET api which returns xml or json representation of an object instance using JaXB. Everything is fine as long as I can get this instance based on id and return it. But when I don't find instance what should I return. I know 404 response has to be returned. But my method already returns a given type. So how do I setup 404 status is response?
Here is simplified version of my method
#GET
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public GameDAO getGameState(#PathParam("gameId") String gameId)
{
//code to get game instance based on gameId
if(game != null)
{
GameDAO d = new GameDAO(game);
return d; //gets auto converted to xml or json
}
return null; //how to return not found response ?
}
A 404 response is what you want, and I think the best way to get there is by throwing a "not found" WebApplicationException. Here's an example:
throw new WebApplicationException(Response.Status.NOT_FOUND);
There are plenty of ways to customize the error handling; you can find more details in the Jersey docs: https://jersey.java.net/documentation/latest/representations.html