I have programmed a backend system in which I can manage data and then output it to an API. I did this because I want to convert a large project to a different language + framework, but I still want to integrate this backend system into the current version first, because it is much better than the old way. I have been looking for days how it works but I haven't really come to a result, I hope someone can help me.
example:
I have a separate page for each member with some data from a biography etc. and I can have this displayed in the WebAPI under: "https://sub.domain.de/items/member" then all members and associated data is output. Now I want that I to: "https://www.domain.de/member/[John_Doe]" (John_Doe is of course an example value for every other member)
can output certain data. the pages should of course still be generated dynamically.
ps: if it is necessary I can also enter "https://sub.domain.de/items/member/[John_Doe]" to only get the data from a specific member.
the json basically looks like this:
{
"data": [
{
"name": "John_Doe",
"status": "published",
"user_created": "052a2c25-b063-4a82-90cb-110d7f809cae",
"date_created": "2021-06-29T08:30:06+02:00",
"title": "Doc John Doe",
"Characteristics": "- **Lorem **: ipsum dolor sit amet\n- **Birthdate**: 1965",
"bio": "- **Lorem ipsum**:\nLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
"member": true,
"section1": false,
"section2": false,
"portrait": null
},
{
"name": "Jane",
"status": "published",
"sort": null,
"user_created": "052a2c25-b063-4a82-90cb-110d7f809cae",
"date_created": "2021-06-29T08:29:31+02:00",
"title": "Jane",
"Characteristics": "",
"bio": "Bio unbekannt.",
"member": true,
"section1": false,
"section2": true,
"potrait": "30d17fe3-bcf7-4aa2-9759-49f3e257eb0f"
}
]
}
and the bio and the characteristics are written in markdown.
I hope I was able to explain what I mean and someone can help me.
edit:
ps: my main problem is that i don't know how to get data from an api, and of course i not only have the area with the members, i still have a lot of articles and more but it works with the same logic.
I guess this totally depending in the routing. you can construct your api that returned the data with this url :"https://sub.domain.de/items/member/[John_Doe]" like so
[Route("items/member")]
[ApiController]
public class UserController : ControllerBase
{
[HttpGet("{username}")]
public IActionResult GetUserData(string username) {
// your logic
}
}
Related
I have created an API for returning website articles :
public function showAllArticles(){
return Article::paginate(10);
}
in the article I have a text body (description) that may have a long text that I won't need, how can I put a str_limit to it ?
Default Output :
{
"current_page": 1,
"data": [
{
"id": 1,
"title": "Ut veniam dolorem et quia. Reprehenderit eum sed doloremque qui est. Sit rerum vel ex quia.",
"slug": "dignissimos-rerum-doloribus-necessitatibus-sit-autem-ad-fuga-cum",
"description": "Deleniti in soluta beatae id ipsa. Quia exercitationem est possimus reiciendis tempora odio. Et perspiciatis dolores dignissimos aperiam voluptatum.\n\nVoluptatem est in maiores porro error qui assumenda. Quaerat eaque vitae neque molestiae laboriosam quis necessitatibus. Vero ut qui sunt. Reiciendis dolorem enim eius recusandae praesentium repellendus.\n\nAd minima deleniti et placeat. Nisi veritatis neque et nobis voluptas. Doloremque officia aperiam aliquid repellendus nesciunt omnis.\n\nEt corrupti et totam est quod dolorum aliquam. Quo sit sequi distinctio inventore eveniet et ut. Ad voluptas perspiciatis incidunt sit. Voluptatem voluptas exercitationem debitis.\n\nEt hic beatae ducimus ad eligendi suscipit. Aut facilis magnam sequi id et ut. Reiciendis sequi iusto maiores nam delectus quasi.\n\nEt in officia earum dolores sunt et. Corrupti voluptatem delectus voluptates exercitationem molestiae aspernatur omnis corrupti. Consectetur sint quos vero nulla id alias. Possimus nam eius molestiae facere et non a.\n\nSint autem debitis corporis animi et beatae et. Aut occaecati nihil et temporibus perferendis. Commodi eligendi quo non et soluta. Vitae dolor sed qui distinctio numquam ad nihil.",
"user_id": 13,
"special": 0,
"image": null,
"created_at": "2021-10-27T21:36:37.000000Z",
"updated_at": "2021-10-27T21:36:37.000000Z"
}, ...
I want to make my "description" to have a lenth limit and add a extra "..." at the end of it.
I have tried this :
$data = Article::paginate(10);
$data->each(function($article){
// I can access each article with $article but I dont know how to modify it in $data
});
You can create an Eloquent: API Resource:
php artisan make:resource ArticleResource
And use the Str::limit helper for that property:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ArticleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'description' => Str::limit($this->description, 50),
//...
];
}
}
Then in your controller return the resource collection:
use App\Http\Resources\ArticleResource;
use App\Models\User;
//...
public function showAllArticles(){
return ArticleResource::collection(Article::paginate(10));
}
You should use the collection function map instead of each, here you can find the documentation for the function: https://laravel.com/docs/8.x/collections#method-map
The map method iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items
EDIT: There is another solution to your issue that would be better in regard of performance, and that is to make the shortening procedure in your query instead of handling it in PHP. Solution can be found here: https://laracasts.com/discuss/channels/laravel/how-to-get-trimmed-value-via-eloquent?page=1&replyId=435130
One solution would be with Custom Resources (like porloscerros already answeared) and one with Accesor. With accesors: You can add the method in your Article model:
use Illuminate\Support\Str;
public funtion getDescriptionAttribute($value)
{
$words = 20;
return Str::of($value)->words($words, ' >>>');
}
server and normally I got it to work. However this time there is an boundary I want to save some time.
I have the following json file:
{ "posts": [
{
"id": 1,
"title": "React",
"category": "React-Development",
"imageUrl": "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg",
"text": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia, molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit,tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit, quia. Quo neque error repudiandae fuga? Ipsa laudantium molestias eos sapiente officiis modi at sunt excepturi expedita sint? Sed quibusdam recusandae alias error harum maxime adipisci amet laborum. Perspiciatis minima nesciunt dolorem! Officiis iure rerum voluptates a cumque velit ",
"date": "23/34/2021"
},
{
"id": 2,
"title": "React",
"category": "React-Development",
"imageUrl": "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg",
"text": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia, molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit,tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit, quia. Quo neque error repudiandae fuga? Ipsa laudantium molestias eos sapiente officiis modi at sunt excepturi expedita sint? Sed quibusdam recusandae alias error harum maxime adipisci amet laborum. Perspiciatis minima nesciunt dolorem! Officiis iure rerum voluptates a cumque velit ",
"date": "23/34/2021"
},
], "category": [
"React-Development",
"Vue3-Topics",
"Angular",
"Backend",
"Vue-Development",
"Angular-Development" ] }
I tried to post with and without Id. Should also work without Id I suppose.
{
"id": 99,
"title": "React",
"category": "React-Development",
"imageUrl": "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_1280.jpg",
"text": "Hello World",
"date": "23/34/2021"
}
However the result I got after a couple of tries.
{
"id": 9
}
Found it! Most likely you didn't change to JSON in the dropdown menu to the right of Body's options row.
I created 2 documents of autogenerated test data in an index/type using:
POST /mymixedata/lists-and-nums/
{
"pat_first_name": "Balduin",
"pat_last_name": "Goodbairn",
"gender": "Male",
"diag_codes": "T84028D",
"prov_first_name": "Dwight",
"prov_last_name": "Croutear",
"prov_addr": "617 Monterey Drive",
"rand_list": [
123,
456,
123
],
"notes": "Quisque porta volutpat erat. Quisque erat eros, viverra eget, congue eget, semper rutrum, nulla. Nunc purus."
}
POST mymixedata/lists-and-nums
{
"pat_first_name": "Goorbi",
"pat_last_name": "Goorbson",
"gender": "Female",
"diag_codes": "S22039D",
"prov_first_name": "Tarrah",
"prov_last_name": "Jimeno",
"prov_addr": "13483 Walton Road",
"rand_list": 100,
"notes": "Phasellus sit amet erat. Nulla tempus. Vivamus in felis eu sapien cursus vestibulum.\n\nProin eu mi. Nulla ac enim. In tempor, turpis nec euismod scelerisque, quam turpis adipiscing lorem, vitae mattis nibh ligula nec sem.\n\nDuis aliquam convallis nunc. Proin at turpis a pede posuere nonummy. Integer non velit.\n\nDonec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec pharetra, magna vestibulum aliquet ultrices, erat tortor sollicitudin mi, sit amet lobortis sapien sapien non mi. Integer ac neque.\n\nDuis bibendum. Morbi non quam nec dui luctus rutrum. Nulla tellus.\n\nIn sagittis dui vel nisl. Duis ac nibh. Fusce lacus purus, aliquet at, feugiat non, pretium quis, lectus."
}
Notice that for the field rand_list, one doc has an array of nums and the other has a single num. Querying the index/type like so:
{
"query": {
"bool": {
"must": [
{
"range": {
"rand_list": {
"gt": "50"
}
}
}
]
}
}
}
I get back both of the documents, which seems like the behavior that I want (assuming its checking the array of nums in the fist doc and the single num in the second to determine if they contain a value > 50).
Other than here, I can't find much documentation on how elastic treats fields that sometimes have arrays and sometimes have single values.
Can anyone explain what's going on? Do single values count as arrays even when they don't have surrounding brackets (ie. is field: 123 same as field: [123] in a doc)?
Thanks :)
Guess I just did not read the docs close enough. Turns out that yes, can have either arrays or single values of same datatype for the same fields in documents.
I have the following file format:
Text1
+ continuation of Text1
+ more continuation of Text1
Text2
+ continuation of Text2
+ more continuation of Text2
+ even more continuation of Text2
Continuations are marked by \n+. (Newline, plus character, space as a three character string.) Continuations can be any number of lines, including 0.
I want the following output (each is a line printed with .forEach):
Text1 continuation of Text1 more continuation of Text1
Text2 continuation of Text2 more continuation of Text2 even more continuation of Text2
I would like to use only Java streams to do the conversion, preferably with Collect. Is there a way to do this elegantly?
EDIT:
Another, more realistic example:
Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt
+ ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex
+ ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit
+ esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+ occaecat cupidatat non proident, sunt in culpa qui officia
+ deserunt mollit anim id est laborum.
Expected result is two lines:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
In Java 9, you could use
static final Pattern LINE_WITH_CONTINUATION = Pattern.compile("(\\V|\\R\\+)+");
…
try(Scanner s = new Scanner(file)) {
s.findAll(LINE_WITH_CONTINUATION)
.map(m -> m.group().replaceAll("\\R\\+", ""))
.forEach(System.out::println);
}
Since Java 8 lacks the Scanner.findAll(Pattern) method, you may add a custom implementation of the operation as a work-around
public static Stream<MatchResult> findAll(Scanner s, Pattern pattern) {
return StreamSupport.stream(new Spliterators.AbstractSpliterator<MatchResult>(
1000, Spliterator.ORDERED|Spliterator.NONNULL) {
public boolean tryAdvance(Consumer<? super MatchResult> action) {
if(s.findWithinHorizon(pattern, 0)!=null) {
action.accept(s.match());
return true;
}
else return false;
}
}, false);
}
which can be used like
try(Scanner s = new Scanner(file)) {
findAll(s, LINE_WITH_CONTINUATION)
.map(m -> m.group().replaceAll("\\R\\+", ""))
.forEach(System.out::println);
}
which will make the future migration easy.
Assuming that you run this sequentially only and really want to use streams:
List<String> result = Files.lines(Paths.get("YourPath"))
.collect(() -> new ArrayList<>(), (list, line) -> {
int listSize = list.size();
if (line.startsWith("+ ")) {
list.set(listSize - 1, list.get(listSize - 1) + line.substring(2));
} else {
list.add(line);
}
}, (left, right) -> {
throw new RuntimeException("Not for parallel processing");
});
I would like to get rid of the close/X button on the top right corner of my Google Closure dialog.
I am browsing the documentation (http://closure-library.googlecode.com/svn-history/r8/trunk/closure/goog/docs/class_goog_ui_Dialog.html) and cannot find the method to do so.
The method is there! See http://closure-library.googlecode.com/svn/docs/class_goog_ui_Dialog.html
dialog.setHasTitleCloseButton(false);
Regards,
Rene
The goog.ui.Dialog title-bar close button can be disabled by first calling goog.ui.Dialog.prototype.getTitleCloseElement() followed by goog.style.showElement(el, display).
Example
var dialog = new goog.ui.Dialog();
dialog.setContent('Lorem ipsum dolor sit amet, consectetuer' +
'adipiscing elit. Aenean sollicitudin ultrices urna. Proin vehicula ' +
'mauris ac est. Ut scelerisque, risus ut facilisis dictum, est massa ' +
'lacinia lorem, in fermentum purus ligula quis nunc. Duis porttitor ' +
'euismod risus. Nam hendrerit lacus vehicula augue. Duis ante.');
dialog.setTitle('Lorem ipsum');
dialog.setButtonSet(goog.ui.Dialog.ButtonSet.createYesNo());
var titleCloseEl = dialog.getTitleCloseElement();
goog.style.showElement(titleCloseEl, false);