I have a webapi project configured with swagger, and I need every endpoint to have their own ID, for documentation and consumption purposes.
I would like this ID to be exposed through swagger and in the swashbuckle UI.
The best approach I can find is to create an attribute and operation filter, and have swashbuckle add it to the operation.description text, but I'd prefer for it to:
a) be its own JSON object in the generated swagger obj, and
b) have its own section in the UI (not 'hack' it into a h4 in the description)
Does anyone know if this is possible?
thanks
Related
I am currently working on a Spring Boot project and I am fairly new to template engines. This will also be my first own private project with Spring Boot.
I would like to know whether it is necessary to include a template engine, such as Thymeleaf, while developing a web application with Spring Boot. I'm using PostegreSQL for the database.
I read under another post that a template engine is not needed, if the backend framework uses JSON for data exchange, because template engines are for rendering retrieved data to HTML for the client. I retrieve JSON objects from the database, can I leave template engines out of my project then?
If any more details are needed, leave a comment below.
No they aren't necessary, in fact most new projects that require web-pages are using single page applications now like Angular, React, Vue, ... over thymeleaf or jsp.
Aside from that a Spring project doesn't always need web pages, for instance when you are just creating a REST API for other applications to call on, or when you are automating things like: a mail service / printing / ... You name it.
However, when you DO want a simple solution with some pages that aren't all that dynamic or complex, pivotal / VMware does recommend to use thymeleaf (over jsp and other solutions) because it integrates easily.
I read under another post that a template engine is not needed, if the backend framework uses JSON for data exchange, because template engines are for rendering retrieved data to HTML for the client. I retrieve JSON objects from the database, can I leave template engines out of my project then?
This is partly true. Yes, Thymeleaf and alike are mostly intended to render data to HTML. They can render any text data, including JSON, but there are tools better suited for the job. On other hand it does not matter how you store the data in your database or what database you are using. You can't just skip rendering (serializing) the response so it does not matter how you store it. What matters is what you want to return as response. For HTML Thymeleaf or even JSP are suitable, but for JSON you may want to use Jackson or Gson instead.
You didn't mentioned the technology you are going to use, so for my examples I'll assume you intend to use Spring Web MVC. Lets take a look at "traditional" controller:
#Controller
public class GreetingController {
#GetMapping("/greeting")
public ModelAndView greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new ModelAndView("greeting", "greeting", new Greeting(name));
}
}
When you make GET request to "/greeting", Spring will call greeting and get the object it returns. In this case it contains the model (the data we want to render) and the view (the template file to use). Then it will try to find a view (something like greeting.html or greeting.jsp) and use template engine like Thymeleaf (or whatever else is configured) to render it (typically to HTML).
What if we want to return JSON instead? In this case we need to:
modify greeting to return Greeting instance instead of ModelAndView
Use RestController instead of Controller. This will tell Spring MVC that we want to directly serialize the object returned to JSON (or similar format) instead of using template to do that.
Here is the modified example:
#RestController
public class GreetingController {
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(name);
}
}
Spring MVC still needs some help to serialize the Greeting instance to JSON. But if you use Spring Boot and the web starter, you don't have to worry about it. It will include Jackson for you.
This is in no way exhaustive answer. As a matter of fact it skips a lot of details, but I hope nevertheless it is useful one. If you want to create REST API using JSON, this Building a RESTful Web Service guide is a good place to start. If you follow the Starting with Spring Initializr steps you'll get a project setup with only what is needed (well maybe with a bit extra but I would not worry too much about it).
Since REST based controller methods only return objects ( not views ) to the client based on the request, how can I show view to my user ? Or maybe better question what is a good way to combine spring-mvc web app with REST, so my user always get the answer, not in just ( for example ) JSON format, but also with the view ?
So far as I understood, REST based controller would be perfectly fitting to the mobile app ( for example twitter ), where views are handled inside the app and the only thing server has to worry about is to pass the right object to the right request. But what about the web app ?
I might be wrong in several things ( correct me if I am ), since I am trying to understand REST and I am still learning.
To simplify things - you basically have two options:
1) Build Spring MVC application.
2) Build REST backend application.
In case of first option - within your application you will have both backend and frontend (MVC part).
In case of second option you build only backend application and expose it through REST API. In most cases, you will need to build another application - REST client for your application. This is more flexible application because it gives you opportunity to access your backend application from various clients - for example, you can have Android, IOS applications, you can have web application implemented using Angular etc...
Please note, that thins are not so simple, you can within one application have both REST backend and REST client etc... This is just very very simplified in order that you get some general picture. Hope this clarified a little things.
There is some additional clarification related to REST and views worth learning. From your question, I can see that you mean "view" in a sense of UI(user interface) and typical MVC usage. But "view" can mean different things in a different contexts.
So:
JSON can be considered as a view for data
JSON is a representation of the resource, just like HTML is
JSON doesn't have style (unless you are not using a browser
extension, which most the users are not using)
The browser is recognizing HTML as a markup language and applying a
style to it
Both are media types
Both JSON and HTML are data formats
Both can be transferred over the wire
This method returns a view
#RequestMapping("/home")
String home(Model model) {
return "home"; // resources\templates\home.html
}
This method Returns String
#RequestMapping(value = "/home")
#ResponseBody
public String home() {
return "Success";
}
If you annotate a method with #ResponseBody, Spring will use a json mapper to generate the response. Instead of annotating every method with #ResponseBody you can annotate your class with #RestController.
If you want to return a view, you need to annotate the class with #Controller instead of #RestController and configure a viewresolver. Bij default spring will use thymeleaf as a viewresolver if you have spring-web as a dependency on the classpath. The return type of the method is a String that references the template to be rendered. The templates are stored in src/main/resources/templates.
You can find a guide on the spring website: https://spring.io/guides/gs/serving-web-content/
I am using a spring boot application and have configured using Swagger UI.
I want to know whether we could pre-populate the example value with sample value so we can hit the "Try it out!" button without having to type in some sample values to get a response.
It must be present there.
Is there a way we can do this using annotations or a separate file which Swagger uses?
I am using a spring boot project with springfox-swagger2:2.7.0 and springfox-swagger-ui:2.7.0 with dependencies added using gradle.
Since the #ApiParam properties example and examples are not working (see this issue on GitHub), support for adding examples is limited/non existing.
What you can do for simple parameters (#RequestParam) is to add the #ApiParam annotation with the defaultValue property, like this:
#GetMapping
public List<Foo> findAll(
#RequestParam(required = false)
#ApiParam(defaultValue = "foo") // Put the default value here
String input) {
// ...
}
However, there is no support yet for doing this with #RequestBody parameters.
A possible workaround for #RequestBody parameters is by clicking on the code box at the right side of the Swagger tester, where it says Example value. If you click on it, it will insert that example into the field itself.
Here is a workaround for providing an example:
Inject html into swagger
#ApiParam(
name="whatever",
value="whatever",
defaultValue="none</p><p>Example: xyz</p>"
)
They don't protect against it in the latest version 2.9.2.
I have a Spring MVC application which returns Json and Xml based on what is requested per client call. I am using Jackson and Xstream to let Spring do the de-serialization of my java object into json or xml output.
My java object contains a bunch of attributes, at least 30. I would like to know if there is a way I can let Spring control which fields of my java object will be present in the json or xml based on a header or parameter attribute. So the client application will be able to identify itself and the backend will return only the fields necessary or "visible" for that specific client app. Of course I could go to the nasty approach of hard coding, but I would not like to do that as the number of client applications can increase or decrease and having a deployment anytime it happens with code changes is out of context.
Is there a way to instruct spring/jackson/xstream to control the output based on some providaded value?
I did a quick implementation and my current solution works like this: I have an xml with a list of client IDs (I use these ids to identify my client app) and for each ID I have a list of attributes that the client app needs from the java object. I created a interceptor and between the controller and the view, my interceptor gets the header information with the client ID, get the list of attributes and using the BeanWrapper (http://docs.spring.io/spring/docs/2.0.x/reference/validation.html) to create a new object with only the attributes required by the client with data, all the others remain null (I instruct Jackson and Xtream) to ignore null attributes. This approach works fine but I was wondering if there is another/better way to do this.
Thank you
TL
As per the title, I'm seeing that my read-only model properties are not serialized in my Web API project. MVC 4 Web API, VS2010.
I've seen a multitude of posts like this stackoverflow question that state that the MVC 4 Web API beta did not support JSON serializing of read-only properties. But many additional references stated that the final release used JSON.NET instead of DataContractJsonSerializer so the issue should be resolved.
Has this issue been resolved or not? If not, am I forced to put in fake setters just to get serialization?
Correction, it does seem to work with JSON (sorry!), but XML exhibits the problem. So same question as before but in the context of XML serialization.
The default JSON serializer is now Json.NET. So readonly property serialization should work without you having to do anything at all.
For XML, in 4.5 we added this flag to the DataContractSerializer:
http://msdn.microsoft.com/en-us/library/vstudio/system.runtime.serialization.datacontractserializersettings.serializereadonlytypes.aspx
You should be able to write something like this:
config.Formatters.XmlFormatter.SetSerializer(myType, new DataContractSerializer(myType, new DataContractSerializerSettings() { SerializeReadOnlyTypes = true });
Place this code in a function called by GlobalConfiguration.Configure in the Application_Start. By default this would be WebApiConfig.Register().