Skip to content

Latest commit

 

History

History
210 lines (158 loc) · 7.69 KB

Readme.adoc

File metadata and controls

210 lines (158 loc) · 7.69 KB

Reading Data from REST Based Source

This example shows an example to read JSON based data from REST endpoint. There may be many examples doing the similar task of reading JSON data into a POJO model using the many data binding libraries like com.fasterxml.databinding libraries. However this example is little different, it does similar task of reloading, however at the end of the example you will end up a JPA entity class that can be used exactly as RDBMS based entity, i.e. you can issue queries against it. Yes, that is correct!, you can issue JPA queries against a JSON document to filter the data, or join the entity with another entity to integrate data. For example, join the JSON data with RDBMS based data. See there is another example on this topic.

What you’ll need

  • About 15 minutes

  • A favorite text editor or IDE

  • JDK 1.11 or later

  • Maven 3.0+

Build With Maven

First you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with Maven is included here. If you’re not familiar with Maven, refer to Building Java Projects with Maven.

Go to Spring Initializer and type in "JPA" in dependencies and generate a project. Then open the generated code in your favorite IDE, and edit the pom.xml to add the below dependencies.

Otherwise, in a project directory of your choosing, create the following sub-directory structure; for example, with

mkdir -p src/main/java/example on *nix systems:

and create pom.xml file of your choosing and add following maven dependencies Spring Boot

spring-boot-starter-data-jpa
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
</dependency>

The following are the Teiid related dependencies

teiid-spring-boot-starter
<dependency>
   <groupId>org.teiid</groupId>
   <artifactId>teiid-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.teiid</groupId>
    <artifactId>spring-data-rest</artifactId>
</dependency>

in this example, we will create Entity class that can read JSON data from web service from http://dummy.restapiexample.com/api/v1/employees which returns JSON data like below. Note that JSON can be complex, for example sake a simple format has been selected.

{
	"status":"success",
	"data":[
		{
			"id":"1",
			"employee_name":"Tiger Nixon",
			"employee_salary":"320800",
			"employee_age":"61",
			"profile_image":""
		},
		{
			"id":"2",
			"employee_name":"Garrett Winters",
			"employee_salary":"170750",
			"employee_age":"63",
			"profile_image":""
		}]
}

Define View/Entity Class

Now it is time to define the main Entity or View class. Since we are reading a Employee let’s call it Employee class

src/main/java/com/example/Employee.java
@JsonTable(endpoint = "webCallBean", source = "rest", root = "/data")
@Entity
public class Employee {

    @Id
    private Integer id;
    private String employee_name;

    public Employee() {
    }

    public Employee(int id, String name) {
        this.id = id;
        this.employee_name = name;
    }

    public Integer getId() {
        return this.id;
    }

    public String getName() {
        return this.employee_name;
    }

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

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

    @Override
    public String toString() {
        return "Value{" + "id=" + id + ", Name='" + employee_name + '\'' + '}';
    }
}

Here you have a Employee class with two attributes, the id, employee_name. You also have two constructors. The default constructor only exists for the sake of JPA. You won’t use it directly. The other constructor is the one you’ll use to create instances of Quote.

The Employee class is annotated with @Entity, indicating that it is a JPA entity. For @Table annotation, is optional, but use it to give a different name. Sometimes @Table also need to be used to avoid the naming conflicts.

The Employee’s id property is annotated with @Id so that JPA will recognize it as the object’s identity. The id property.

The other property, quote is left with out any annotation. It is assumed that they’ll be mapped to columns that share the same name as the properties themselves.

@JsonTable annotation is where most of the magic of Teiid occurring. This defines a query that reading the data from web service, and creating the entity. Note, the source attribute must be set to rest and endpoint attribute needs to be set to the location of the service. If there are custom headers need to be defined use @RestConfigutaion annotation and set required properties on it on this entity class.

At application boot time, Teiid Spring Boot scans the application’s packages for these annotations and builds the respective metadata required to create a virtual database internally and deploys to server. To do this scan, define the application package name in this property to the application.properties file.

src/main/resources/application.properties
spring.teiid.model.package=org.example

In absence of this property entire classpath is scanned, that could take significant time depending upon all the libraries in your application.

For more available annotations, refer to Reference Guide.

The convenient toString() method will print out the Quote’s properties.

Create simple queries

Spring Data JPA focuses on using JPA to store data in a relational database. Its most compelling feature is the ability to create repository implementations automatically, at runtime, from a repository interface.

To see how this works, create a repository interface that works with Quote entities:

src/main/java/org/example/EmployeeRepository.java
@Repository
public class EmployeeRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<Employee> findAll() {

        List<Employee> result = jdbcTemplate.query("SELECT id, employee_name FROM Employee",
                (rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("employee_name")));
        return result;
    }
}

EmployeeRepository uses JDBCTemplate interface to work with JPA entities.

Spring Data JPA also allows you to define other query methods by simply declaring their method signature. In a typical Java application, you’d expect to write a class that implements EmployeeRepository. But that’s what makes Spring Data JPA so powerful: You don’t have to write an implementation of the repository interface. Spring Data JPA creates an implementation on the fly when you run the application.

Let’s wire this up and see what it looks like!

Create an Application class

Here you create an Application class with all the components.

src/main/java/org/example/Application.java
package org.example;

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Autowired
    RestTemplate restTemplate;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args).close();
    }

    @Override
    public void run(String... args) throws Exception {
        employeeRepository.findAll().forEach(c -> System.out.println("***" + c));
    }
}

Now when you execute this application, you should see results like below.

***Value{id=1, Name='Tiger Nixon'}
***Value{id=2, Name='Garrett Winters'}
***Value{id=3, Name='Ashton Cox'}