Hey everyone. π€© I am writing this article to guide you through to a create a dynamic GraphQL schema programmatically as java code. We would be primarily using the graphql-java
library for this.
GraphQL Schema
GraphQL has its type system thatβs used to define the schema of an API. The syntax for writing schemas is called Schema Definition Language (SDL). We can either define the schema using SDL or define it programmatically as java code. But both of them are static ways of representation. In case you are building schema during runtime, it becomes difficult to recursively add new fields to your predefined definition.
SDL Schema Definition
type Customer {
name : String
address : String
contact : Int
}
Programmatic Schema Definition
GraphQLObjectType.Builder graphQLObjectType = GraphQLObjectType.newObject();
graphQLObjectType.name("Customer")
.field(newFieldDefinition()
.name("name")
.type(Scalars.GraphQLString))
.field(newFieldDefinition()
.name("address")
.type(Scalars.GraphQLString))
.field(newFieldDefinition()
.name("conatct")
.type(Scalars.GraphQLInt)
.build();
We will be focusing on how to extract the metadata of the data source to which you are connecting. Metadata characterizes your data and makes easier for anyone to understand and consume it. To put it simply, metadata is the data describing the data that is being stored in your data source. It generally includes the name, size and number of rows of each table present in a database, along with the columns in each table, their data types, precisions, etc.
Let's get started! π
To read and store database meta data we will be using two interfaces DatabaseMetaData
and ResultSet
.The DatabaseMetaData interface is huge, containing hundreds of methods for reading capabilities of a DBMS. You can refer to Javadoc for the complete list of methods.
Obtaining DatabaseMetaData Instance
Here I am using jdbc-url for Teiid
, you can choose others too. We obtain the DatabaseMetaData
object from a Connection
object, like this:
String URL = "jdbc:teiid:customer@mm://localhost:31000";
String USERNAME = "sa";
String PASSWORD = "sa";
Connection connection = DriverManager.getConnection(URL, USERNAME ,PASSWORD );
DatabaseMetaData databaseMetaData = connection.getMetaData();
Listing Database Tables
We can obtain a list of the defined tables in your database or data source with the help of DatabaseMetaData. Here is how that is done:
String table[] = {"TABLE"};
ResultSet resultSet = databaseMetaData.getTables(null,null,null,table);
ArrayList<String> tables = new ArrayList();
while(resultSet.next()) {
tables.add(resultSet.getString("TABLE_NAME"));
}
Listing Database Columns
We can obtain the columns of a table via the DatabaseMetaData object in this manner :
ResultSet columns = databaseMetaData.getColumns(null,null, tableName, null);
while(columns.next()) {
String columnName = columns.getString("COLUMN_NAME");
String datatype = columns.getString("DATA_TYPE");
String columnsize = columns.getString("COLUMN_SIZE");
System.out.println(columnName + "---" + datatype + "---" + columnsize);
}
Creating Schema
Next step would be to create a schema using GraphQLObjectType
object, store it's corresponding metadata in HashMap and read it's type from ReturnType
class defined in the next section.
ResultSet resultSet = databaseMetaData.getColumns(null, null, (String) tableName, null);
GraphQLObjectType objectType = null;
GraphQLObjectType.Builder graphQLObjectType = GraphQLObjectType.newObject();
System.out.println("-------Schema for Table " + tableName + "-------");
HashMap <String,String> data = new HashMap<>();
while (resultSet.next()) {
data.put(resultSet.getString("COLUMN_NAME"), resultSet.getString("TYPE_NAME"));
for (Map.Entry<String, String> hm : data.entrySet()) {
graphQLObjectType
.name(tableName)
.field(GraphQLFieldDefinition.newFieldDefinition()
.name(hm.getKey())
.type(ReturnType(hm.getValue())));
objectType = graphQLObjectType.build();
}
}
Defining the Field Type in Schema
This class returns the type of field in each case, here I have defined only two types GraphQLLong
and GraphQLString
. You can define accordingly for other types.
public static GraphQLScalarType ReturnType(String type) {
if(type.equals("long"))
return Scalars.GraphQLLong;
else if (type.equals("string"))
return Scalars.GraphQLString;
return null;
}
}
Building and Printing Schema
To print schema is a defined manner we are using SchemaPrinter
object which takes an object of GraphQLSchema type.
GraphQLSchema graphQLSchema = GraphQLSchema.newSchema()
.query(objectType)
.build();
SchemaPrinter schemaPrinter = new SchemaPrinter();
String printer = schemaPrinter.print(graphQLSchema);
System.out.println(printer);
Conclusion
There you have it! You have successfully connected to your data source to fetch database metadata and using the data you constructed your graphQL schema.
You can visit the Github Repo Schema Builder to view the source code. Also check GraphQL Java website to learn more.
You're learning. I'm learning. We're all learning. Let's continue to learn and get better together. Thank you. Happy Reading! π
Top comments (1)
Hi ,
I have a requirement to generate dynamic query of GraphQL from schema. I need to create dynamic schema and its query by passing table name from the database. I am able to create schema dynamically. Can anyone help me to create dynamic queries on it?
Thanks