Elements Manual
Elements 3 Manual
Elements 3 Manual
  • Welcome 👋
  • QUICK START
    • Elements in Five Minutes or Less
    • Accessing the Web UI (CRM)
    • Creating A User
  • General
    • General Concepts
    • N-Tier Architecture
    • Security Model
  • Core Features
    • Core API Overview
    • Sessions
    • Applications
    • Users and Profiles
    • Digital Goods
    • Progress and Missions
    • Leaderboards
    • Matchmaking
    • Followers
    • Friends
    • Reward Issuance
    • Save Data
    • Schemas and Metadata Specifications
    • Queries
      • Base Query Syntax
      • Boolean Queries
      • Object Graph Navigation
      • Advanced Operators
        • .ref
        • .name
    • Custom Code
      • Element Structure
      • RESTful APIs
      • Websockets
    • Auth Schemes
      • OIDC
      • OAuth2
  • Web 3
    • Omni Chain Support
    • Vaults
    • Wallets
    • Smart Contracts
      • Smart Contracts: Ethereum
      • Smart Contracts: Flow
      • Smart Contracts: Solana
      • Smart Contracts: Neo
  • CONFIGURATION
    • Direct Database Access and Batch Configuration
    • Batch Samples
      • Item Upload Bash Script Sample
      • Mission Upload Bash Script Sample
  • RESTful APIs
    • Swagger and Swagger UI
    • API Specification
      • /application
      • /application/configuration
      • /auth
      • /auth_scheme
        • /custom
        • /oauth2
        • /oidc
      • /blockchain
      • /followee
      • /follower
      • /friend
      • /google
      • /index
      • /inventory
      • /item
      • /large_object
      • /leaderboard
      • /rank
      • /score
      • /match
      • /mission
      • /progress
      • /reward_issuance
      • /schedule
      • /notification
      • /profile
      • /save_data
      • /metadata_spec
      • /mock_session
      • /session
      • /health
      • /version
      • /signup
      • /user
    • Javadocs
  • Releases
    • 3.1 Release Notes
    • 3.2 Release Notes
Powered by GitBook
On this page
  • Steps to Defining a Jakarta RS Element
  • Complete Example Code
  1. Core Features
  2. Custom Code

RESTful APIs

How to build RESTful APIs in Elements

PreviousElement StructureNextWebsockets

Last updated 2 months ago

Elements 3.0 Provides a complete implementation of . The full usage of Jakarta RS is beyond the scope of this document. What you need to know most:

  • Jakarta RS Allows you to generate RESTful endpoints for your game's code which can be called from in-engine code using any standard HTTP client library.

  • Specific endpoints are developed using a set of in Java code and handled automatically by the application container.

  • Existing RESTul APIs can be imported directly into an Element with almost no modification.

Steps to Defining a Jakarta RS Element

To use the Jakarta RS in your own Element, you must perform the following steps:

  • by annotating the package-info type in your code.

  • Add all compiled classes and jars into the .

  • Expose the type as a service.

Complete Example Code

The following example walks through the necessary files to define a simple endpoint for CRUD (Create, Read, Update, Delete) operations for a message based service.

Step 1: Define the Element

package-info.java
@ElementDefinition
package dev.getelements.elements.sdk.test.element.rs;

import dev.getelements.elements.sdk.annotation.ElementDefinition;

Step 2: Define the Application

TestApplication.java
package dev.getelements.elements.sdk.test.element.rs;

import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider;
import dev.getelements.elements.sdk.annotation.ElementDefaultAttribute;
import dev.getelements.elements.sdk.annotation.ElementServiceExport;
import dev.getelements.elements.sdk.annotation.ElementServiceImplementation;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

import java.util.Set;

@ApplicationPath("/")
@ElementServiceImplementation
@ElementServiceExport(Application.class)
public class TestApplication extends Application {

    @ElementDefaultAttribute("myapp")
    public static final String APP_SERVE_PREFIX = "dev.getelements.elements.app.serve.prefix";

    @Override
    public Set<Class<?>> getClasses() {
        return Set.of(
                MessageEndpoint.class,
                JacksonJsonProvider.class
        );
    }

}

Step 3: Define the Endpoint Code

MessageEndpoint.java
package dev.getelements.elements.sdk.test.element.rs;

import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;

import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;

@Path("/message")
public class MessageEndpoint {

    private static final AtomicInteger counter = new AtomicInteger();

    private static final Map<Integer, Message> messages = new ConcurrentSkipListMap<>();

    @POST
    public Response createMessage(
            final CreateMessageRequest createMessageRequest) {

        if (createMessageRequest.getMessage() == null) {
            return Response.status(Response.Status.BAD_REQUEST).build();
        }

        final int id = counter.incrementAndGet();
        final long now = System.currentTimeMillis();

        final var message = new Message();
        message.setId(id);
        message.setMessage(createMessageRequest.getMessage());
        message.setCreated(now);
        message.setUpdated(now);

        if (messages.putIfAbsent(id, message) != null) {
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
        }

        return Response
                .status(Response.Status.CREATED)
                .entity(message).build();

    }

    @PUT
    @Path("{messageId}")
    public Response updateMessage(
            @PathParam("messageId")
            final String messageId,
            final UpdateMessageRequest updateMessageRequest) {

        final int id;

        try {
            id = Integer.parseInt(messageId);
        } catch (NumberFormatException ex) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        final var result = messages.computeIfPresent(id, (_id, existing) -> {
            final var updated = new Message();
            updated.setId(_id);
            updated.setCreated(existing.getCreated());
            updated.setUpdated(System.currentTimeMillis());
            updated.setMessage(updateMessageRequest.getMessage());
            return updated;
        });

        return result == null
                ? Response.status(Response.Status.NOT_FOUND).build()
                : Response.status(Response.Status.OK).entity(result).build();

    }

    @GET
    public Response getMessages() {
        return Response
                .status(Response.Status.OK)
                .entity(messages.values())
                .build();
    }

    @GET
    @Path("{messageId}")
    public Response getMessage(
            @PathParam("messageId")
            final String messageId) {

        final int id;

        try {
            id = Integer.parseInt(messageId);
        } catch (NumberFormatException ex) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        final var message = messages.get(id);

        return message == null
                ? Response.status(Response.Status.NOT_FOUND).build()
                : Response.status(Response.Status.OK).entity(message).build();

    }

    @DELETE
    @Path("{messageId}")
    public Response deleteMessage(
            @PathParam("messageId")
            final String messageId) {

        final int id;

        try {
            id = Integer.parseInt(messageId);
        } catch (NumberFormatException ex) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        final var removed = messages.remove(id);

        return removed == null
                ? Response.status(Response.Status.NOT_FOUND).build()
                : Response.status(Response.Status.NO_CONTENT).entity(removed).build();

    }

}

Step 4: Ensure all Dependencies are Included

pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>dev.getelements.elements</groupId>
        <artifactId>eci-elements</artifactId>
        <version>2.2.0-SNAPSHOT</version>
    </parent>

    <artifactId>sdk-test-element-rs</artifactId>
    <version>2.2.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>dev.getelements.elements</groupId>
            <artifactId>sdk</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jakarta.ws.rs</groupId>
            <artifactId>jakarta.ws.rs-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
            <artifactId>jackson-jakarta-rs-json-provider</artifactId>
            <version>2.18.3</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.6.0</version> <!-- Use the latest version -->
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/libs</outputDirectory>
                            <includeScope>runtime</includeScope>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
Jakarta RESTful Web Services 4.0.0
annotations
Application
Define the Element
Element package structure