Saturday, February 18, 2023

Ace the 1Z0-819 Java SE 11 Developer Exam: Your Step-by-Step Guide

Oracle Certified Professional - Java SE 11 Developer, Oracle Java 11 Mock Test, 1Z0-819, Oracle 1Z0-819 Questions and Answers, Oracle Java SE 11, 1Z0-819 Study Guide, 1Z0-819 Practice Test, Oracle Java SE 11 Developer Certification Questions, 1Z0-819 Sample Questions, 1Z0-819 Simulator, Oracle Java SE 11 Developer Online Exam, Oracle Java SE 11 Developer, 1Z0-819 Certification, Java SE 11 Developer Exam Questions, Java SE 11 Developer, 1Z0-819 Study Guide PDF, 1Z0-819 Online Practice Test, 1z0-819 dumps, 1z0-819 exam questions, 1z0-819 exam, java se 11 developer 1z0-819 dumps, 1z0-819 preparation, oracle 1z0-819, 1z0-819 syllabus, java se 11 developer exam number: 1z0-819, 1z0-819 questions, 1z0-819 exam dumps, java se 11 developer 1z0-819 practice tests, 1z0-819 mock exam free, java 1z0-819, java se 11 developer 1z0-819 syllabus, java se 11 programmer i 1z0-819 book pdf free download, 1z0-819 mock exam, 1z0-819 book pdf, java 11 certification dumps 1z0-819, java se 11 developer 1z0-819 pdf, java se 11 developer certification (1z0-819), java se 11 developer 1z0-819 ocp, java se 11 developer 1z0-819, java se 11 developer exam questions, java se 11 certification questions
Java is a powerful and popular programming language used by developers worldwide. As the language evolves, so do the certifications and exams that certify developers' skills and knowledge. The 1Z0-819 exam is a new Java SE 11 Developer exam that tests your proficiency in Java SE 11. Passing this exam can open up new career opportunities and demonstrate your expertise to employers. This article will provide a step-by-step guide to clearing the 1Z0-819 exam, including essential concepts, study resources, and tips.

Understanding the 1Z0-819 Exam

Before diving into how to pass the 1Z0-819 exam, it's essential to understand what this exam tests and how it's structured. The 1Z0-819 exam tests your proficiency in Java SE 11, including core language features, APIs, and libraries. The exam consists of 80 multiple-choice questions and lasts for 180 minutes. To pass the exam, you must score 63% or higher.

Step 1: Review the Exam Objectives

The first step to passing the 1Z0-819 exam is to review the exam objectives. These objectives provide a detailed breakdown of the topics covered on the exam and can help you focus your studying. The exam objectives for the 1Z0-819 exam can be found on the Oracle website.

Step 2: Use Study Resources

To pass the 1Z0-819 exam, you must have a strong understanding of Java SE 11 and be familiar with the exam's structure and format. The following study resources can help you prepare for the exam:
  • Oracle Certified Professional - Java SE 11 Developer Certification Study Guide: This guide covers all the topics on the exam and includes practice questions to test your knowledge.
  • Java SE 11 Documentation: This is an essential resource for understanding the core language features, APIs, and libraries covered on the exam.
  • Practice tests: Taking practice tests can help you get a feel for the format and difficulty of the actual exam. You can find several practice tests online.
  • Study groups: Joining a study group can help prepare for the 1Z0-819 exam. You can find study groups online or form one with other developers in your area. A study group can allow you to discuss concepts, ask questions, and share study resources.

Step 3: Study and Practice Coding

Once you have familiarized yourself with the exam objectives and study resources, the next step is to start studying and practicing coding. To improve your coding skills, try to solve coding challenges and exercises, and review the Java SE 11 documentation to ensure that you deeply understand the language.

Step 4: Take 1Z0-829 Practice Tests

Taking practice tests is an essential part of preparing for the 1Z0-819 exam. Practice tests can help you get a feel for the format and difficulty of the actual exam, and they can also help you identify areas where you need to improve your knowledge and skills.

Step 5: Take the Exam

Once you have completed your studying and practice tests, it's time to take the actual exam. Make sure to arrive at the testing center early and bring all the necessary materials, including a valid ID. Read the instructions carefully, and take your time answering the questions. If you get stuck on a question, skip it and return to it later.

It's essential to manage your time wisely during the exam. You have 180 minutes to answer 80 multiple-choice questions, which gives you approximately 2 minutes per question. Try to spend only a little time on any question, and if you need clarification on an answer, make an educated guess and move on.

Conclusion

Passing the 1Z0-819 exam can open up new career opportunities and demonstrate your expertise to employers. However, it requires hard work, dedication, and preparation. By understanding the exam objectives, using the right study resources, practicing coding, and taking practice tests, you can easily increase your chances of passing the exam. Remember to manage your time wisely during the exam and follow the instructions carefully. You can become a certified Java SE 11 Developer with the right mindset and approach. Good luck!

Friday, February 17, 2023

Java Management Service introduces new Advanced Features for customers and makes Basic Discovery available to everyone

With the latest release of Java Management Service (JMS) Oracle introduces several new advanced features to help administrators gain additional insights into Java workloads. JMS administrators can now use Java Management Service - Fleet Management to:

◉ Analyze the usage of application servers
◉ Identify potential vulnerabilities associated with the Java libraries used by applications
◉ Assess the impact of Oracle JRE and JDK Cryptographic Roadmap changes on their applications
◉ Use Java Flight Recorder to gather application insights
◉ Download and install Oracle Java versions
◉ Remove Oracle Java versions

on Desktops, Servers, or Cloud deployments covered by an Oracle Java SE Subscription or when running on an Oracle Cloud Infrastructure service that permits access to the underlying operating system.

As announced during the JavaOne 2022 Keynote, the Basic Java Management Service Discovery Features that identify Java Runtimes and Oracle JDK usage is now available to everyone, even users that do not have a Java SE Subscription or are running in Oracle Cloud Infrastructure.

New Advanced Features


In addition to Java Runtime Lifecycle Management Operations, JMS has introduced more advanced features - Advanced Usage Tracking, Crypto event analysis, and JDK Flight Recording. These new advanced features are currently supported on Linux platforms.

Advanced usage tracking

Basic usage tracking which relies on Java usage tracker and file scanning capabilities helps JMS administrators to identify Oracle JDK usage and report OpenJDK distributions. Advanced usage tracking will help in identifying usage of Java severs and Java libraries.

Scan for Java servers

JMS administrators can use the "Scan for Java servers" operation in Java Management Service - Fleet Management, to detect and report usage of application and HTTP servers like Oracle Weblogic, Apache Tomcat, and JBoss. In addition to the versioning info, JMS administrators can also see the applications deployed on these servers and the Managed Servers to which the servers are deployed.

Java Management Service, Oracle Java Certification, Oracle Java Career, Java Skills, Java Jobs, Java Prep, Java Preparation, Java Certification
Java Application Servers

Java Management Service, Oracle Java Certification, Oracle Java Career, Java Skills, Java Jobs, Java Prep, Java Preparation, Java Certification

Applications running in each Java Application Server

Scan for Java libraries

The "Scan for Java libraries" creates a list of Java libraries used by Java applications (both standalone and those deployed in Java servers) in the fleet. JMS will also compare the libraries and versions found against the National Vulnerability Database to help administrator identify applications that should be updated to use newer versions or updated to different libraries.

The scans for advanced usage tracking must be initiated by the JMS administrator and is not performed by default by the JMS agents.

Java Management Service, Oracle Java Certification, Oracle Java Career, Java Skills, Java Jobs, Java Prep, Java Preparation, Java Certification
Java libraries detected by JMS in the fleet

Crypto event analysis

Oracle's plans for changes to the security algorithms and associated policies/settings in the Oracle Java Runtime Environment (JRE) and Java SE Development Kit (JDK) are published periodically at Oracle JRE and JDK Cryptographic Roadmap. To make good use of that information however, administrators would need to know if any of their Java applications are using the algorithms, key lengths, or default values that will be changed. Some of that information can be hard to know, especially when applications rely on configurations on the servers they connect to.

Using Crypto Event Analysis, administrators will get detailed information on what cryptographic algorithms from the Java Security Libraries are being used. JMS will compare the algorithms being used with the planned changes and highlight applications that might be impacted by future changes or by certificates that are about to expire.  When applicable, JMS will provide  recommendations to avoid disruptions.

Java Management Service, Oracle Java Certification, Oracle Java Career, Java Skills, Java Jobs, Java Prep, Java Preparation, Java Certification
Results of Crypto event analysis run on a managed instance in the fleet

Please be aware that JMS can only identify cryptographic usage within the JDK libraries. JMS can identify usage of most third-party cryptographic providers but cannot provide details of which algorithms or certificates are being used when relying on third-party cryptographic providers.

JDK Flight Recording

Administrators can initiate Java Flight Recording on applications reported by JMS using the Run JDK Flight Recorder (JFR) operation in Java Management Service - Fleet Management. JDK Flight Recorder collects diagnostic and profiling data about a running Java application. JMS will initiate the recording and upload the resulting JFR file to the customer’s tenancy, enabling administrators to do their own analysis of the recordings.

Java Management Service, Oracle Java Certification, Oracle Java Career, Java Skills, Java Jobs, Java Prep, Java Preparation, Java Certification
Initiating Java Flight Recording for an application

Basic Java discovery available for all!


We are excited to announce that Basic Java discovery of JMS is now available to all Java users, whether they have a Java SE Subscription, are running on OCI, or not. Basic Discovery allows you to:

◉ View the versions and vendor information of all Java runtimes in your systems
◉ Identify which Oracle Java installations are up to date, and which ones should be updated or upgraded
◉ View which applications run on each Oracle Java runtime

To take advantage of JMS Basic Discovery administrators will need to create an OCI Account, go to Java Management Service, and create one or more fleets (to group the managed instances).  Once you have created your fleet(s), you install the Java Management Service agent on each system you would like to monitor. The JMS agent will scan your systems to find all Java installations and configure usage logging on all Oracle Runtimes to start collecting information on what Java Applications are using them. All information collected by JMS is stored in your user tenancy. Although there is no charge for using JMS you will be responsible for storage costs for the information collected by the agent (starting $0.01 per MB per month).

Source: oracle.com

Wednesday, February 15, 2023

Differences Between Oracle JDK and OpenJDK

Oracle JDK, OpenJDK, Oracle Java Tutorial and Materials, Oracle Java Career, Java Prep, Oracle Java Certification, Java Guides, Java Prep, Oracle Java Preparation

Java has been one of the most popular programming languages in the world for many years, and for good reason. It is versatile, reliable, and scalable, making it an excellent choice for developing everything from small mobile apps to large enterprise systems. However, when it comes to choosing a Java Development Kit (JDK) for your project, you may be wondering what the differences are between Oracle JDK and OpenJDK. In this article, we will explore the key differences between the two JDKs and help you make an informed decision on which one is right for your project.

What is Oracle JDK?


Oracle JDK is the official implementation of Java Standard Edition (Java SE), developed and maintained by Oracle Corporation. It is the original implementation of Java, and it includes all the features and components required to develop, run, and debug Java applications. Oracle JDK is available under a commercial license, which means that if you want to use it for commercial purposes, you will need to purchase a license from Oracle.

What is OpenJDK?


OpenJDK, on the other hand, is an open-source implementation of Java SE, developed and maintained by the Java community. It is an alternative to Oracle JDK, and it includes all the features and components required to develop, run, and debug Java applications. OpenJDK is available under the GNU General Public License, which means that it is free to use for commercial and non-commercial purposes.

Key Differences between Oracle JDK and OpenJDK


1. Licensing

One of the key differences between Oracle JDK and OpenJDK is the licensing. Oracle JDK is available under a commercial license, which means that if you want to use it for commercial purposes, you will need to purchase a license from Oracle. OpenJDK, on the other hand, is available under the GNU General Public License, which means that it is free to use for commercial and non-commercial purposes.

2. Support

Another important difference between Oracle JDK and OpenJDK is the support. Oracle provides commercial support for Oracle JDK, which includes bug fixes, security updates, and technical support. OpenJDK, on the other hand, is community-supported, which means that there is no formal support from any organization. However, many companies and individuals provide community support for OpenJDK, which includes bug fixes, security updates, and technical support.

3. Release Schedule

Oracle JDK and OpenJDK also have different release schedules. Oracle releases a new version of Oracle JDK every six months, and provides support for each version for at least three years. OpenJDK, on the other hand, is released by different vendors, each with its own release schedule. Some vendors release a new version of OpenJDK every six months, while others release it every few years. The length of support for each version of OpenJDK also varies depending on the vendor.

4. Features

While both Oracle JDK and OpenJDK include all the features and components required to develop, run, and debug Java applications, there are some differences in the implementation. Oracle JDK includes some proprietary features that are not available in OpenJDK, such as Java Flight Recorder and Java Mission Control. However, these features are available in OpenJDK if you use a build that includes them.

Which one should you choose?


Choosing between Oracle JDK and OpenJDK depends on your specific needs and requirements. If you require commercial support, then Oracle JDK may be the better choice for you. If you are looking for a free and open-source alternative, then OpenJDK may be the better choice. It is also worth noting that some third-party vendors provide commercial support for OpenJDK, so you may be able to get the support you need without purchasing a license from Oracle.

Monday, February 13, 2023

Quiz yourself: Splitting Java streams and using escape characters

Oracle Java, Oracle Java Tutorial and Materials, Oracle Java Prep, Oracle Java Guides, Oracle Java Certification, Java Career, Java Jobs, Java Skill

Test your knowledge of the Pattern class and splitAsStream method


Given the following class

import java.util.Arrays;
import java.util.regex.Pattern;
public class FooBaz {
  static final Pattern PIPE_SPLITTER = Pattern.compile("\\|");
  public static void main(String[] args) {
    System.out.print(doIt("12|11|30"));
  }
  public int doIt(String s) {
    var a = PIPE_SPLITTER.splitAsStream(s)
       .mapToInt(v -> Integer.valueOf(v))
       .mapToObj(v -> new Integer[]{v % 3 == 0 ? 1 : 0, v % 5 == 0 ? 2 : 0, v})
       .reduce(new Integer[]{0, 0, 0}, (i, is) -> new Integer[]{i[0] + is[0], i[1] + is[1], i[2] + is[2]});
    return Arrays.stream(a).mapToInt(Integer::intValue).sum();
  }
}

What is the result? Choose one.

A. 56 is the output.
B. 57 is the output.
C. 58 is the output.
D. 59 is the output.
E. Compilation fails.

Answer. When you see an exam question that has unreasonably complex code, be sure to check for simple things first. You won’t always find the answer there, but if checking the hard stuff is going to take a long time, it’s smart to check the easy stuff first. In this example, the code does not, in fact, compile. The reason is simple: The static main method attempts to call the doIt method without any explicit prefix, and such an invocation can work only for a static doIt() method. However, doIt() is an instance method and in the absence of an explicit prefix, such an invocation will fail. From this you can quickly determine that option E is correct, mark that as your answer, and move on to the next question.

Now that you know the correct answer, let’s make this discussion more interesting by pretending that the doIt() method was static or that an explicit instance prefix was provided for the invocation of the doIt() method.

First, notice that the splitAsStream method splits the string argument "12|11|30" into three text chunks—"12", "11", and "30"—which are then converted to a stream of equivalent primitive int values by the mapToInt operation.

As side notes, observe three things: the use of the Pattern class’s splitAsStream method, the precompilation of the pattern, and the escaping of the vertical bar character in the regular expression pattern.

◉ The splitAsStream method is more direct than the more common approach of extracting items from the source text to an intermediate array using the simple split method and then making a stream from the elements of the array as a second step.

◉ The precompilation of the regular expression pattern makes no difference here, but notice that the pattern is declared as a static final, rather than being embedded in the body of the method. Turning a textual regular expression into the representation that actually performs pattern matching is a fairly CPU-intensive task, so it’s generally a good idea to arrange that a pattern is precompiled in this way just once, rather than referring to it in the string literal form in a way that might involve it being compiled each time a loop executes that code.

◉ Note the nature of the regular expression literal. The simple vertical bar (or pipe) character represents an OR operation and must be escaped. However, a single backslash would be an attempt to escape the vertical bar in the parsing of the string literal, which is probably not what you want. You need to make a literal containing the character sequence “backslash, vertical bar.” Because backslash is itself the escape character, it must be escaped, so two backslashes in the source code make one in the binary code, which is what’s desired.

Going back to the operation of this stream, the three int values are mapped to a stream of Integer arrays, containing the following data:

[1, 0, 12]
[0, 0, 11]
[1, 2, 30]

Notice that the conditional operators in the mapToObj argument will put 0 in the first array element if the int in the stream is exactly divisible by 3 but put 1 in otherwise. The second element of the array will be 0 if the int is exactly divisible by 5 but will be 2 otherwise. The third element is simply the int value from the stream.

Next the stream is reduced to a single Integer[] by summing values with the same indices to produce the following result in the variable a:

[2, 2, 53]

In the final step, the array noted above is converted to a stream of Integer objects, which are then converted to primitives and then reduced to the sum of all elements, producing 57 as the output. Thus, if the code had actually compiled, option B would have been correct.

Conclusion. The correct answer is option E.

Source: oracle.com

Friday, February 10, 2023

Quiz yourself: Handling side effects in Java

Oracle Java, Oracle Java Tutorial and Materials, Oracle Java Prep, Oracle Java Preparation, Oracle Java Certification, Oracle Java Learning, Oracle Java Guides

This question exemplifies a style that’s popular with test creators. It’s less popular with candidates.


Imagine that your colleague is prototyping new business logic that must work in a multithreaded application and has created the following class:

class MyRunnable implements Runnable {
    public void run() {
        synchronized (MyRunnable.class) {
            System.out.print("hello ");
            System.out.print("bye ");
        }
    }
}

To test the class, your colleague wrote the following method and then invoked the method, passing a Stream object containing two MyRunnable instances:

public static void testMyRunnable(Stream<Runnable> s) {
    s.map(
        i -> {
            new Thread(new MyRunnable()).start();
            return i;
        }
    ).count();
}

A. The output will be exactly hello bye hello bye.
B. The output will always start with hello followed by either hello or bye.
C. No output will be produced.
D. None of the above.

Which statement is correct? Choose one.


Answer. This question exemplifies a style that’s popular with test creators, but perhaps it’s less popular with candidates. The setup makes the question appear to be on one topic, when in fact it’s really about something else. In this case, the question probably appears to be about threading and mutual exclusion using synchronization. It’s really about the Stream API.

Oracle Java, Oracle Java Tutorial and Materials, Oracle Java Prep, Oracle Java Preparation, Oracle Java Certification, Oracle Java Learning, Oracle Java Guides
Look at the method and its invocation. The test method receives a Stream as an argument, calls a map() operation on that stream, and then executes the count() terminal operation on the resulting stream. You know from the question that the Stream argument has two items in it, so the count() method must return 2.

Here is the detail that matters most: If the Stream object is one for which the size is known without having to draw elements to exhaustion, the count() method might actually return that size without ever processing the body of the stream. Indeed, the documentation for the count() method states the following:

An implementation may choose to not execute the stream pipeline (either sequentially or in parallel) if it is capable of computing the count directly from the stream source. In such cases no source elements will be traversed and no intermediate operations will be evaluated. Behavioral parameters with side-effects, which are strongly discouraged except for harmless cases such as debugging, may be affected.

In other words, if the argument stream has a known size, there will be no output at all. If, however, the argument stream has a size that is not known until it runs, some output will be produced.

The side effects of printing “hello ” and “bye ” are therefore not impossible but are also not guaranteed. Options A, B, and C are therefore incorrect, and option D must be the correct answer.

To dig deeper, let’s investigate this idea of a stream having a known or unknown element count. The following streams have exactly two elements:

List.of(1, 3).stream()
Stream.of(1, 3)

However, because some of the elements might be removed, the following stream has an element count that must be determined dynamically:

List.of(1, 3).stream.filter(x -> 3 * Math.random())

Given that this kind of side effect can be ignored—the documentation calls it elided—how should you write code intended to be used in the map method and related methods? The guidance is that the operations passed as arguments to the methods of a stream should generally be pure functions. A key (but not the only) feature of a pure function in programming (as distinct from mathematical theory) is that it does not have observable side effects. (Printing a message is typically considered to be a visible side effect, though logging messages might not be considered visible. It’s complicated and what’s visible depends a bit on perspective.)

On this topic, the documentation has more to offer.

The eliding of side-effects may also be surprising. With the exception of terminal operations forEach and forEachOrdered, side-effects of behavioral parameters may not always be executed when the stream implementation can optimize away the execution of behavioral parameters without affecting the result of the computation.

As mentioned earlier, this question looks as if it’s about synchronization. So, in the interest of completeness, consider how this aspect will behave if the map method’s argument is invoked with each element of the stream.

The body of the run() method is synchronized on the java.lang.Class object that describes MyRunnable in the running VM (that is, MyRunnable.class). This is, in effect, a static element and, therefore, no matter how many instances of this particular MyRunnable class might exist, only one thread can be in the process of executing the sequence of print statements. That tells you that if any thread manages to print “hello ” it must continue to print “bye ” before any other thread can print anything. This would mean that, if the stream actually processed its elements through the map operation, the output would be as shown in option A.

Conclusion. The correct answer is option D.

Source: oracle.com

Monday, February 6, 2023

Curly Braces #8: REST peacefully with GraphQL and Java

GraphQL can be a very efficient way of transferring data via API calls.


I’ve been RESTing happily since the early 2000s after Roy Fielding’s doctoral dissertation, “Architectural styles and the design of network-based software architectures,” caused many in the software world to move to representational state transfer (REST) to solve their API needs.

Oracle Java, Java Exam, Java Tutorial and Materials, Java certification, Java Prep, Java Preparation, Java Guides, Java Graph

Prior to that, I was building web-enabled software services, called service-oriented architecture (SOA) or web services. REST helped to formalize API definitions, but SOA and web services were essentially equivalent to traditional approaches in two key ways: The API developer predetermines both the endpoints and the data returned for each API.

Over the past few years, many have come to consider REST the de facto standard for API usage, even for noninternet applications. It’s easy to embed a web server to serve up a REST API, and there are plenty of frameworks available to enable it. Additionally, REST APIs are language- and platform-neutral, and those APIs are often used as a facade to enable legacy applications in a modern web or mobile application architecture. In this article, I’ll talk about both REST and another architecture, GraphQL.

REST has drawbacks


Although REST solves many API-related problems, it’s not perfect. The architecture’s deficiencies include the following.

Overfetching. REST APIs are defined to return data as a predefined structure, usually in XML or JSON. If a caller wants only some fields of data returned, too bad: They get all the data anyway. This doesn’t seem like a big deal, but this inefficiency adds up when an API returns multiple records.

Underfetching. You may need to make multiple REST calls to aggregate all the data you need for one user or back-end operation. The associated round trips are inefficient and can lead to multiple database transactions.

Overfetching and underfetching. Ironically, underfetching often leads to overfetching, because one or more of the REST calls required to satisfy a single user operation likely contain data that’s not needed or that’s duplicated..

Implicit intent. REST is built upon HTTP, and it leverages GET and PUT/POST calls to indicate read or write operations. With REST, it’s frowned upon to name API calls explicitly, for example, GetUser or CreateUser. Instead, you are encouraged to name the API and the user, and then rely on the HTTP operation that’s used to imply the intent. For example, an HTTP GET is equivalent to GetUser, PUT is equivalent to either UpdateUser or CreateUser, a POST is usually equivalent to CreateUser but sometimes to UpdateUser, and DELETE is equivalent to DeleteUser. Because of this, the API’s intent can be hidden behind the communication protocol, so it isn’t always obvious. It’s also not a precise match; hence, the confusion between POST, PUT, and PATCH.

Lack of agility. Each REST API call exists and returns the prescribed data only because its creator decided it should. Even if the API is well designed, it’s unlikely to serve every client’s needs precisely, and changing needs will render it less of a fit over time. Additionally, once APIs are used, it’s difficult or impossible to change them without impacting external applications. Building dependencies between applications is less than agile.

Introducing GraphQL


In 2012, developers at Facebook developed an improvement on REST, which was then released as an open source data query language called GraphQL.

GraphQL is similar to REST except that it’s data oriented: The caller precisely defines the data to be returned, and the server complies by returning that data and nothing else. For instance, if a user wants to know the balance for a bank account, the front-end code will make a call to a GraphQL web interface using a JSON-like request such as the one shown in Listing 1. (The ssn field is for a nine-digit identifier issued by the US government called a Social Security Number.)

Listing 1. A sample GraphQL query

{
    account {
        id(id: "987654321")
        name
        type
        customer {
            firstName
            lastName
            ssn
        }
        availableBalance
        totalBalance
    }
}

The server will fulfill the query with a JSON-compliant response, as shown in Listing 2.

Listing 2. A sample GraphQL query response

{
  "data": {
    "account": {
      "id": "987654321",
      "name": "Personal Checking",
      "type": "Basic Checking",
      "customer": {
        "firstName": "Eric",
        "lastName": "Bruno",
        "ssn": "123-45-6789"
      },
      "availableBalance": "1234.56",
      "totalBalance": "1234.56"
    }
  }
}

In this case, the identification of the bank account is provided as an input key for lookup. So far, this is a straightforward query. However, consider that this single GraphQL call combines data from multiple resources: the user as well as basic account and balance information from the bank.

By contrast, common REST APIs often break this into multiple endpoints and calls: one for the balance of the given account number, another for account data, and yet another for user data. Additionally, there’s likely a lot more data about the account and the user than what was returned here.

Individual REST calls to get user and account information would likely have resulted in overfetching, which is inefficient and may even be a security risk in a financial application.

Looking inside GraphQL


Although GraphQL’s name contains the word graph, the architecture doesn’t supply true graph operations. However, GraphQL does provide a type system with introspection, a defined query language, and execution semantics with explicit indication of reads and writes. A single request, called a query, can return data for more than one resource, as shown in the previous example, by following references between them.

In other words, GraphQL queries allow you to express relationships in the call itself, dynamically, offering efficiency and flexibility.

Unlike REST APIs, which use endpoints to describe and group operations, GraphQL organizes them by schemas, data types, and associated fields. Types are used to constrain requests to only what is feasible, and they indicate how data is to be used. Using the query in Listing 1, related GraphQL types might look like Listing 3.

Listing 3. GraphQL types for the query in Listing 1

type Query {
    account: Account
}

type Account {
    id: Int
    name: String
    type: [
        "Basic Checking"
        "Advanced Checking"
        "Business Checking"
    ]
    owner: Customer
    availableBalance: Balance
    totalBalance: Balance
}

type Customer {
    firstName: String
    lastName: String
    ssn: String
    address: Address
    phone: Phone
    email: String
    active: Boolean
}

type Address {
    street: String
    city: String
    state: [
      "Alabama"
      "Alaska"
      ...
    ]
    zip: String
}

type Phone {
    ...
}

type Balance {
    amount: Float
    asOf: Date
    ...
}

As shown in this example, the GraphQL type system is expressive and comprehensive.

GraphQL mutations


Notice that the GraphQL description for type in Listing 3 begins with the keyword Query. This indicates that this is a read schema. GraphQL provides the mutation schema to mark an API as writable. It’s a requirement that every GraphQL API have a query type, but a mutation type is optional, and it is similar to queries in that you specify nested fields and a return type. The following is an example of the mutation type definition:

mutation CreateAccount($account: Account,) {
    createAccount(account: $account) {
        id
        name
    }
}

The createAccount mutation creates a new account and returns the id and name of that account. The matching request, which is an input object type, would look like the following:

{
  "account": {
    "name": "Personal Checking",
    "type": "Basic Checking",
    "customer": {
    "firstName": "Eric",
    "lastName": "Bruno",
    "ssn": "...",
    "address": "...",
    "phone": "...",
    "email": "eric@ericbruno.com",
    "active": "true"

    }
  }
  :
}

The result would be the new account id and name, as shown below.

{
  "data": {
    "createAccount": {
      "id": "987654321",
      "name": "Personal Checking",
      "Customer:" {
        "ssn": "..."
      }
    }
  }
}

The mutation in this example can create a new customer along with the account or return an existing customer if the record is located with the ssn provided; GraphQL is flexible this way.

The GraphQL schema includes more advanced features, such as interfaces, lists, the ability to specify bounds on fields, enumerations, unions, inputs, operations, and more. There’s also a sophisticated validation schema based on the GraphQL type system.

Java and GraphQL


GraphQL includes open source helper code in many languages, including Java, to make it easy to create and consume GraphQL APIs.

On GitHub, you’ll find Java classes to help generate queries, define schemas, execute queries, and parse the results. Other GraphQL Java libraries are available and also integrate with other tools and server frameworks such as Spring.

Source: oracle.com