Wednesday, March 16, 2022

JavaScript Fetch API CRUD

 

Fetch API

The Fetch API provides a interface for fetching resources including across the network. It will seem familiar to anyone who has used XMLHttpRequest, however the new API provides a more powerful and flexible  feature set.

Browser compatibility























Fetch Rest  CRUD API 

These are APIs that we need to provide:

MethodsUrls
GET/posts
GET/posts/{id}
POST/posts
PUT/posts/{id}
DELETE/posts/{id}

Technology

  • JavaScript
  • Stackblitz
  • JSONPlaceholder

Ok. let go.


Project Structure





















Service js


const endPoint = 'https://jsonplaceholder.typicode.com';

async function getAll() {
const response = await fetch(`${endPoint}/posts`);
const data = await response.json();
return data;
}

async function getById(code) {
const response = await fetch(`${endPoint}/posts/${code}`);
const data = await response.json();
return data;
}

async function savePost() {
const response = await fetch(`${endPoint}/posts`, {
method: 'POST',
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1,
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
});
const data = await response.json();
return data;
}

async function updateResourse(code) {
const response = await fetch(`${endPoint}/posts/${code}`, {
method: 'PUT',
body: JSON.stringify({
id: 1,
title: 'foo',
body: 'bar',
userId: 1,
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
});
const data = await response.json();
return data;
}

async function del(code) {
const response = await fetch(`${endPoint}/posts/${code}`, {
method: 'DELETE',
});
const data = await response.json();
return data;
}

export { getById, getAll, savePost, updateResourse, del };



Index js


// Import stylesheets
import './style.css';
import { getById, getAll, savePost, updateResourse, del } from './services.js';

// Write Javascript code!
const appDiv = document.getElementById('app');
const appDiv1 = document.getElementById('app1');
const appDiv2 = document.getElementById('app2');
const appDiv3 = document.getElementById('app3');
const appDiv4 = document.getElementById('app4');

(function () {
// your page initialization code here
// the DOM will be available here

getIdPost();
getAllPost();
savPosts();
//upResource();
// deleteById();
})();

async function deleteById() {
let json;
await del(1).then(function (data) {
json = data;
});
appDiv4.innerHTML = JSON.stringify(json);
}

async function upResource() {
let json;
await updateResourse(1).then(function (data) {
json = data;
});
appDiv3.innerHTML = JSON.stringify(json);
}

async function savPosts() {
let json;
await savePost().then(function (data) {
json = data;
});
console.log(json);
appDiv2.innerHTML = JSON.stringify(json);
}
async function getAllPost() {
let json;
await getAll().then(function (data) {
json = data;
});
appDiv1.innerHTML = JSON.stringify(json);
}

async function getIdPost() {
let json;
await getById(1).then(function (data) {
json = data;
});
appDiv.innerHTML = JSON.stringify(json);
}



Index html


<div><h2>GET BY ID https://jsonplaceholder.typicode.com/posts/1</h2></div>
<div id="app"></div>
<div><h2>POST https://jsonplaceholder.typicode.com/posts</h2></div>
<div id="app2"></div>
<div><h2>PUT https://jsonplaceholder.typicode.com/posts/1</h2></div>
<div id="app3"></div>
<div><h2>DELETE https://jsonplaceholder.typicode.com/posts/1</h2></div>
<div id="app4"></div>
<div><h2>GET ALL https://jsonplaceholder.typicode.com/posts</h2></div>
<div id="app1"></div>



Run & Test




























Source Code


Here on Stackblitz.





References.

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
https://www.javascripttutorial.net/javascript-fetch-api/
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
https://jsonplaceholder.typicode.com/guide/


















VScode watcher limit Ubuntu 20.04

Visual Studio Code is unable to watch for file changes in this large workspace


When you see this notification, it indicates on your project it had many files and you need to change default value watchers (8192), provide Linux VM, because it is insufficient to the tasks, The watchers is part inotify Linux kernel subsystem.  

If you want to see your default watchers run the following command.

$ cat /proc/sys/fs/inotify/max_user_watches

If you get many files on your project then the default watcher is not enough to monitor all files.
you need increased for listen to work properly.

Increased limit temporary run the following command

$ sudo sysctl fs.inotify.max_user_watches=524288

$ sudo sysctl -p


Increased limit permanet run the following command

$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf

$ sudo sysctl -p





















Friday, March 4, 2022

Quarkus Spring Data API PostgreSQL CRUD

Quarkus A Kubernetes Native Java stack tailored for OpenJDK HotSpot and GraalVM, crafted from the best of breed Java libraries and standards.

CREATING A Quarkus APPLICATION

In this example we're integration Quarkus + Spring Data API + PostgreSQL.

  • Configuration Quarkus, Spring Data and PostgreSQL.
  • Define Datas models, Repository and Services.
  • Quarkus Resource.

Quarkus Rest  CRUD API 

These are APIs that we need to provide:

Methods Urls
GET /users
GET /users/age/{age}
POST /users/name/{name}/age/{age}
PUT /users/id/{id}/age/{age}
DELETE /users/{id}

Technology

  • Java 17
  • Quarkus 2.7.3.Final
  • PostgreSQL 14.1 
  • Maven 
  • Postman v9.0.8
  • IntelliJ IDEA 2021.2.3 
  • Docker

Project Structure


























Configuration  Quarkus Spring Data PostgreSQL


pom.xml


<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.henry</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<failsafe.useModulePath>false</failsafe.useModulePath>
<maven.compiler.release>11</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>2.7.3.Final</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>JBoss repository</id>
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>2.2.1.GA</version>
</dependency>

<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>2.2.0.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.6.2.Final</version>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-spring-data-jpa</artifactId>
</dependency>


<!-- JDBC driver dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>
org.jboss.logmanager.LogManager
</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager
</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
  

application.properties


quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=quarkus_test
quarkus.datasource.password=quarkus_test
quarkus.datasource.jdbc.url=jdbc:postgresql:quarkus_test
quarkus.datasource.jdbc.max-size=8
quarkus.datasource.jdbc.min-size=2
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.http.port=9000

Set up PostgreSQL


docker run -it --rm=true --name quarkus_test -e POSTGRES_USER=quarkus_test -e POSTGRES_PASSWORD=quarkus_test -e POSTGRES_DB=quarkus_test -p 5432:5432 postgres:14.1

Data class model


package com.henry.model;

import javax.persistence.*;

@Entity
@Table(name="USERS")
public class User {

@Id
@SequenceGenerator(name = "USERS_id", sequenceName = "USERS_id", initialValue = 1, allocationSize = 1)
@GeneratedValue(generator = "USERS_id")
private Long id;

private String name;
private Integer age;

public User(){}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}
}

Repository Interface


package com.henry.repository;

import com.henry.model.User;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface UserRepository extends CrudRepository<User, Long> {

List<User> findByAge(Integer age);
}

Service Interface



package com.henry.service;

import com.henry.model.User;

import java.util.List;
import java.util.Optional;

public interface UserService {

public Iterable<User> findAll();
public Optional<User> findById(long id);
public void delete(long id);
public User create(String name,Integer age);
public User changeAge(Long id,Integer age);
public List<User> findByAge(Integer age);
}

Service Class

package com.henry.service.impl;

import com.henry.model.User;
import com.henry.repository.UserRepository;
import com.henry.service.UserService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {

private final UserRepository userRepository;

public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Override
public Iterable<User> findAll() {
return userRepository.findAll();
}

@Override
public Optional<User> findById(long id) {
return userRepository.findById(id);
}

@Override
public void delete(long id) {
userRepository.deleteById(id);
}

@Override
public User create(String name, Integer age) {
return userRepository.save(new User(name, age));
}

@Override
public User changeAge(Long id, Integer age) {
Optional<User> optional = userRepository.findById(id);
if (optional.isPresent()) {
User user = optional.get();
user.setAge(age);
return userRepository.save(user);
}

throw new IllegalArgumentException("No User with id " + id + " exists");
}

@Override
public List<User> findByAge(Integer age) {
return userRepository.findByAge(age);
}
}

Quarkus Rest APIs Resource


package com.henry.resource;

import com.henry.model.User;
import com.henry.service.UserService;
import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/users")
public class UserResource {

private final UserService userService;

public UserResource(UserService userService) {
this.userService = userService;
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public Iterable<User> findAll() {
return userService.findAll();
}


@DELETE
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public void delete(@PathParam long id) {
userService.delete(id);
}

@POST
@Path("/name/{name}/age/{age}")
@Produces(MediaType.APPLICATION_JSON)
public User create(@PathParam String name, @PathParam Integer age) {

return userService.create(name, age);
}

@PUT
@Path("/id/{id}/age/{age}")
@Produces(MediaType.APPLICATION_JSON)
public User changeAge(@PathParam Long id, @PathParam Integer age) {
return userService.changeAge(id, age);
}

@GET
@Path("/age/{age}")
@Produces(MediaType.APPLICATION_JSON)
public List<User> findByAge(@PathParam Integer age) {

return userService.findByAge(age);
}
}

Run & Test


Run Quarkus application with next maven command :
./mvnw compile quarkus:dev or ./mvnw test (Run test class) by console or IntelliJ.




GET.










 














GET.



























POST.


























PUT.






















DELETE.























Source Code


Here on Github.



References.



https://quarkus.io/guides/spring-data-jpa














Automating Deployments with CronJobs in Google Kubernetes Engine (GKE)

In the realm of container orchestration, automation plays a pivotal role in streamlining operations. Google Kubernetes Engine (GKE) offers r...