How can I convert a URL (http://127.0.0.1:8080/authors/1) to domain object?
I will let my clients submit URLs as foreign keys and I have to resolve them somehow.
For example I want to create a book with the author 1
POST /books
{"title":"Harry Potter", "author":"http://127.0.0.1:8080/authors/1"
I found a class named UriToEntityConverter that sounds right but of course 0 tutorials or examples.
I am serving my objects from a #RestController.
you could simply define your path using request mapping and store the variable using pathVariable annotation
#RequestMapping(value="/authors/{id}", method=RequestMehtod.POST)
public RequestEntity<String> doSomething(#PathVariable("id") long id) //id will contain your id
Related
If for example an Asset contains Relationships property for owner then when using GetSingle API (from a client App) we get back something like: "owner":"resource:somenamespace.owner#owner01". (i.e. related participant is owner with ownerId = owner01).
What is actually being returned for the relationship property?
Is there anyway we can actually get back all the properties of the related instance (owner with ownerId = owner01) in the same call? I have tried adding parameter to the Rest call such as below but no joy.?resolve=true&include=true.
If I can't get related instance properties in same Rest call then how do I extract out the related Id (e.g. owner01 in above example) from the returned "owner":"resource:somenamespace.owner#owner01"I can then do a separate GetSingle call to the owner Rest end point using the extracted ownerId?I have tried searching the web for docs on such Rest API parameters/processing of results but no joy.Many thanks.Lalji
1) What's returned is a URI resource ID for the related object (ie owner)
2) Yes. Use Loopback filters to resolve. For example ('GET' call - eg. using httpClient or axios etc eg - two examples:
GET 'http://localhost:3000/api/CommodityAsset?filter={"where":{"assetId":"A01"},"include":"resolve"}' // narrow filter - for one asset
GET 'http://localhost:3000/api/CommodityAsset?filter={"where":{"ownerId":"resource:org.acme.biznet.owner%23T01"},"include":"resolve"}' // broader, assets owned by a particular owner, could be many
where %23 is '#' the encoded character used in Composer language relationship notation.
I have an application with urls like site.com/article/1/title.htm
I have #RequestMapping /article/{id}/{title}.htm that server this request and gets the article.
What I am looking achieve is to have a url like site.com/title.htm but cant think of a way to do that using Spring MVC because I need id of the article. any ideas? Thanks in advance
When you create an article, you need to create the SEO-friendly URL also and persist it, along with the article. Now you need to have a repository method that allows you to retrieve articles by permalink, and a Spring MVC endpoint that calls that repository method.
Using the title may not be a good idea, as the title is usually not URL-friendly, and may eventually be non-unique. But it is a good idea to use the title as the input for the permalink.
Here's a sample permalink algorithm:
Take the title
replace all occurrences of one or more space or punctuation with a single dash
replace all non-ascii characters with their ascii neighbors
check whether that permalink already exists
if it does, add a counter
This is how the read path could look like:
#Autowired
private ArticleRepository ar;
#RequestMapping(value="/article/{id}/{ignored}") #ResponseBody
public Article getByIdAndIgnorePermalink(#PathVariable String id, #PathVariable String ignored){
return ar.getById(id);
}
#RequestMapping(value="/article/{title}.html") #ResponseBody
public Article getByPermalink(#PathVariable String permalink){
return ar.getByPermalink(permalink);
}
There is no way send hidden id obviously, so it has to be done through a permalink of the article or simply via title, to achieve site.com/title.html you need to get rid of all the fixed bits by adding this request mapping rule:
#RequestMapping(value = "/**/{articleTitle}.html"
but to get the article you can obviously use id as its not there in the URL and have to work with that articleTitle or generate a permalink as suggested by #Sean above.
We have a Spring MVC webapp and our product URL structure needs to be SEO friendly. Such as www.mydomain.com/{productname}. Every time we add a product to inventory, we want to have URL to display those product details.
We could not figure our how to generate dynamic URLs with Spring Controller Resource path.
Can someone please help us.
Would appreciate your help.
Thanks
Raj
A Spring URL structure like www.mydomain.com/{productname} would seem to imply that 'productname' is always unique. If so, each product could have a property called 'name' or 'productname'; this property could be used to retrieve the relevant product in your controller method. This will only work if every 'productname' is unique.
What you are looking for is URI Template Patterns. In Spring MVC, #PathVariable annotation is used to bind an argument to the value of URI template variable.
#RequestMapping(path="/{productname}", method=RequestMethod.GET)
public String findProduct(#PathVariable String productname, Model model) {
List<Product> product = productService.findProductsByName(productname);
model.addAttribute("product", product);
return "displayProduct";
}
Note that the service call returns List<Product> instead of one Product, since ideally, product name is not unique to one item. If you want the URI to identify exactly one product, make sure that product name is unique to one product only.
What is the best practice for obtaining an entity from a link in spring-hateoas?
I have two independent entities, author and document, where documents have can have multiple authors, but authors can exist without being linked to any documents.
To fetch the authors for a given document, there is an endpoint at /documents/{id}/authors which returns a list of the authors and their links.
An author is added to a document by issuing a POST of a link entity to /documents/{id}/authors where the entity contents are the same as a org.springframework.hateoas.Link, that is to say a rel and an href:
{
"rel": "author",
"href": "http://localhost:8081/authors/50"
}
I want to be able to do a service call like:
service.addAuthor(documentId, authorId);
documentId is provided as a #PathVariable, while authorId is embedded in the href.
In order to get authorId, I currently use spring's RequestMappingHandlerMapping and the controller class for the entity type (author in this case) to fetch the RequestMapping for the entity's GET method and fetch the id uri template variable for the href provided in the link. Finally, I have to parse this as a number.
Is there some better/built-in way of doing this?
Using spring-hateoas 0.17.0, if that is relevant.
Is it possible to have the Help Page sample generator ignore certain properties of a particular type?
For example, we use the same DTO for object Request and Response messages, for both POST and PUT requests. When user is POSTing a model (creating a new record) they don't need to provide the ID field.
But once its created and we serialize the new record into the response body, the ID field is included and returned to the client.
So in the POST request sample, I don't want the ID field to be displayed because for post request it doesn't make sense.
But the POST response sample, I do want the ID field displayed...
I am aware that there is the ApiExplorerSettings attribute which can be applied to a Class or Method...but is there anything similar for a Property?
Something like this would be great:
public class MyDTO
{
[ApiExplorerSettings(IgnoreForRequestApi = true, IgnoreForResponseApi = false)]
public int Id { get; set; }
// Other properties omitted for brevity...
}
Using the following annotation I've successfully hidden a property from the generation!
[ApiExplorerSettings(IgnoreApi = true)]
No, there isn't a similar option for a property. HelpPage uses formatter instances configured on the application to serialize the samples and as you can imagine the formatters must not have this knowledge within themselves.
Regarding workarounds:
a. You could explicitly set the raw sample for a particular action's requestsample via the SetSampleRequest extension of HttpRequestMessage. You should be able to see some examples about this in the file at *Areas\HelpPage\App_Start\HelpPageConfig.cs*.
b. In the file Areas\HelpPage\SampleGeneration\HelpPageSampleGenerator.cs, there is a method called WriteSampleObjectUsingFormatter which uses the application's formatter instances to write the samples. Here you would need to create new formatter instances having similar settings as your normal application has(so that they reflect the exact serialization/deserialization semantics that your application would normally react to when actual requests are made) and then try to hide the properties which you want to. We want to create new instances because we do not want to disturb the normal functioning of the application.
Example: In case of Json, you could create a new Json formatter instance and provide a ContractResolver which can hide the properties. Check this link: http://james.newtonking.com/projects/json/help/html/ConditionalProperties.htm
In case of Xml, I am not sure how we can hide properties without using the IgnoreDataMember attribute and also being non-intrusive.
Currently I would prefer option 'a' as its comparatively a simple workaround than 'b'.
ASP.NET WEB API uses Json.NET for JSON and DataContarctSerailizer for XML formatting so if you add [JsonIgnore] annotations over properties that you do not want included in your serialization should work just fine.