DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How To Build Web Service Using Spring Boot 2.x
  • Aggregating REST APIs Calls Using Apache Camel
  • Composite Requests in Salesforce Are a Great Idea
  • How to Do API Testing?

Trending

  • Java 23 Features: A Deep Dive Into the Newest Enhancements
  • How to Build Local LLM RAG Apps With Ollama, DeepSeek-R1, and SingleStore
  • A Guide to Container Runtimes
  • Segmentation Violation and How Rust Helps Overcome It
  1. DZone
  2. Data Engineering
  3. Databases
  4. Creating Entities in a Spring Boot/Elide JSON API Server

Creating Entities in a Spring Boot/Elide JSON API Server

Learn how to update the application to allow new entities to be created.

By 
Matthew Casperson user avatar
Matthew Casperson
·
May. 17, 16 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
7.6K Views

Join the DZone community and get the full member experience.

Join For Free

In a previous article, I showed you how to create a Spring Boot application that integrated the Elide JSON API library to create a read-only REST API. In part 2, we’ll update the application to allow new entities to be created.

The JSON API supports the HTTP POST verb for creating new entities, and for creating new to-many relationships. We’ll add support for these two REST endpoints in our application.

First, though, we have some house keeping to do. As you saw in the first article, we have to do some work to prepare Elide once a request has been received: get the Hibernate Session Factory, find the complete request URL, create a logger, and then create the Elide object itself. This code is going to be shared between all Elide operations, so it makes sense to move it into a common location.

/**
     * All our elide operations require similar initialisation, which we perform in this method before calling
     * elideCallable with the elide object and the path that elide needs to know what it is supposed to do.
     * @param request The request
     * @param elideCallable A callback that is used to execute elide
     * @return The response to the client
     */
    private String elideRunner(final HttpServletRequest request, final ElideCallable elideCallable) {
        /*
            This gives us the full path that was used to call this endpoint.
         */
        final String restOfTheUrl = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);

        /*
            Elide works with the Hibernate SessionFactory, not the JPA EntityManagerFactory.
            Fortunately we san unwrap the JPA EntityManagerFactory to get access to the
            Hibernate SessionFactory.
         */
        final SessionFactory sessionFactory = emf.unwrap(SessionFactory.class);

        /*
            Elide takes a hibernate session factory
        */
        final DataStore dataStore = new HibernateStore(sessionFactory);

        /*
            Define a logger
         */
        final Logger logger = new Slf4jLogger();

        /*
            Create the Elide object
         */
        final Elide elide = new Elide(logger, dataStore);

        /*
            There is a bug in Elide on Windows that will convert a leading forward slash into a backslash,
            which then displays the error "token recognition error at: '\\'".
         */
        final String fixedPath = restOfTheUrl.replaceAll("^/", "");

        /*
            Now that the boilerplate initialisation is done, we let the caller do something useful
         */
        return elideCallable.call(elide, fixedPath);
    }


The new elideRunner() method is almost a line for line copy of what used to be found in the method that responded to the GET request. The only real differences are that we don’t process the request parameters (because, as we’ll see, the Elide post() method doesn’t require these), and that we defer the actual execution of the Elide library to an interface that takes the newly created Elide object and the path of the request.

/**
 * We'll implement this interface as a lambda to make working with Elide easier
 */
public interface ElideCallable {
    String call(final Elide elide, final String path);
}


Before we handle the POST request, let’s look at what the GET request method now looks like:

    @CrossOrigin(origins = "*")
    @RequestMapping(
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE,
            value={"/{entity}", "/{entity}/{id}/relationships/{entity2}", "/{entity}/{id}/{child}", "/{entity}/{id}"})
    @Transactional
    public String jsonApiGet(@RequestParam final Map<String, String> allRequestParams, final HttpServletRequest request) {
        /*
            Here we pass through the data Spring has provided for us in the parameters, then making
            use of Java 8 Lambdas to do something useful.
         */
        return elideRunner(
                request,
                (elide, path) -> elide.get(path, fromMap(allRequestParams), new Object()).getBody());
    }


We have effectively reduced the method to a single line of code, making use of Java 8 lambdas to execute the Elide library’s get() method.

Not surprisingly, the method handling the POST request is very similar.

    @CrossOrigin(origins = "*")
    @RequestMapping(
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            value={"/{entity}", "/{entity}/{id}/relationships/{entity2}"})
    @Transactional
    public String jsonApiPost(@RequestBody final String body, final HttpServletRequest request) {
        /*
            There is not much extra work to do here over what we have already put in place for the
            get request. Our callback changes slightly, but we are still just passing objects
            from Spring to Elide.
         */
        return elideRunner(
                request,
                (elide, path) -> elide.post(path, body, new Object(), SecurityMode.SECURITY_INACTIVE).getBody());
    }


Like its GET counterpart, the method handling the POST request does nothing more than pass the parameters supplied by Spring into Elide, making use of the common functionality now abstracted away by the elideRunner() method.

To create a new entity, POST the following JSON to the http://localhost:8080/parent endpoint:

{
  "data": {
    "type": "parent",
    "attributes": {
      "description": "James drives a racecar",
      "name": "James"
    }
  }
}


The response will be something like this:

{
  "data": {
    "type": "parent",
    "id": "12",
    "attributes": {
      "description": "James drives a racecar",
      "name": "James"
    },
    "relationships": {
      "children": {
        "data": []
      }
    }
  }
}


To define a relationship between a parent and a child, POST the following to http://localhost:8080/parent/12/children endpoint:

{
  "data": { "type": "child", "id": "1" }
}


The response will be something like this:

{
  "errors": [
    "com.yahoo.elide.core.exceptions.ForbiddenAccessException: ForbiddenAccess not shared child#1"
  ]
}


This is because Elide has a security layer which prevents these relationships from being defined without some additional code. In the next article, we’ll take a look at these security annotations and give ourselves the ability to define relationships between entities.

Grab the source code for this project from GitHub.

JSON API Spring Framework entity Requests

Opinions expressed by DZone contributors are their own.

Related

  • How To Build Web Service Using Spring Boot 2.x
  • Aggregating REST APIs Calls Using Apache Camel
  • Composite Requests in Salesforce Are a Great Idea
  • How to Do API Testing?

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: