Skip to content
  • Our Product
    • Namazu Elements
      • What is Elements?
      • Why open source?
      • Docs
        • Namazu Elements in Five Minutes or Less
        • RESTful APIs Library
        • Security Model
        • Accessing the Web UI (CMS)

    Our Product

    A logomark with three layered rhombuses adorning the lettermark that says Elements in bold all-caps sans-serif letters.
    • What is Namazu Elements? Discover our easy-to-use backend network solution built for online games. Rapidly enables full-scale multiplayer games or online solo adventures.
    • Why open source? Is there a truly open source server backend for connected games? There is now. Download and run a local copy of Namazu Elements and try it for yourself.
    Download Namazu Elements

    Get started

    • Quick start Read our Elements 5-minute quick start guide
    • Documentation Read our developer docs for learning more about Elements
    • RESTful APIs A full list of core API specs for working with the Elements framework
    • Security An overview of the server-authoritative security model of Elements
    • Accessing the CMS Manage your game with ease via the Namazu Elements CMS.

    Co-development Reimagined

    • Reduce your costs Would you rather outsource your backend development? Hire Namazu Studios to build your server backend with the power of Namazu Elements.
      Co-dev

    Recent Posts

    • The watercolor-styled Namazu Studios logo over a giant namazu lurking in the depth
      Namazu Studios Featured in San Diego Business Journal
      22 Sep 2025 Press
    • Namazu Elements 3.1 Released – Service Layer Fixes, Secure APIs, and Steam Bug Fix
      22 Apr 2025 Release Notes
  • Case Studies
  • About Us
  • News
  • Services
  • Book a call
namazu-studios-logo
Book a call

Getting Started

  • Namazu Elements in Five Minutes or Less
  • Accessing the Web UI (CMS)
  • CMS Feature Overview

Fundamentals

  • Why You Need a Server (and What “Authoritative” Means)
  • Elements as a Game Runtime
  • Where Your Authoritative Code Runs
  • Lifecycles and Flows

General Concepts

  • Overview
  • Custom Elements
  • Data Models
  • Security Model
  • N-Tier Architecture

Namazu Elements Core Features

  • User Authentication / Sign In
    • What is a User?
    • User Authentication in Elements
    • Auth Schemes
      • Auth Schemes
      • OAuth2
      • OIDC
  • Features
    • Applications
    • Sessions
    • Users and Profiles
    • Digital Goods
    • Progress and Missions
    • Progress and Missions (3.4+)
    • Leaderboards
    • Matchmaking – Comprehensive Guide
    • Followers
    • Friends
    • Receipts
    • Reward Issuances
    • Save Data
    • Metadata
    • Metadata (3.4+)
    • Queries
    • Web3
      • Wallets
      • Vaults
      • Omni Chain Support
      • Smart Contracts
        • Smart Contracts
  • Queries
    • Advanced Operators
    • Object Graph Navigation
    • Boolean Queries
    • Base Query Syntax
  • Advanced Operators
    • .name
    • .ref

Your Game Code - Adding Custom Elements

  • Custom Code Overview
  • Windows Setup
  • Mac OS Setup
  • Ubuntu Linux Setup
  • Element Anatomy: A Technical Deep Dive
  • Introduction to Guice and Jakarta in Elements
  • Structuring your Element
  • Events
  • Packaging an Element with Maven
  • Deploying an Element
  • Preparing for code generation
  • Properties
  • Websockets
  • RESTful APIs
  • Direct MongoDB Access (3.5+)

Configuration

  • Matchmaking – Comprehensive Guide
  • Direct Database Access and Batch Configuration
  • Batch Samples
    • Mission Upload Bash Script Sample
    • Item Upload Bash Script Sample

RESTful APIs

  • Importing into Postman
  • RESTful APIs Library
  • Swagger and Swagger UI

Add-Ons

  • Custom Elements
    • Crossplay
      • Namazu Crossfire (Multiplayer)
      • Deploying Namazu Crossfire in your game
  • Game Engines
    • Unity
      • Elements Codegen
      • Crossfire
    • Roblox
      • Roblox Overview
      • Secure Player Authentication & Registration
      • Global Matchmaking
      • Roblox Security Best Practices

Troubleshooting

  • Common Issues with Docker
  • Local SDK
    • Unable to deploy application : dev.getelements.elements.sdk.exception.SdkElementNotFoundException
    • Could not load class : java.lang.NoClassDefFoundError
  • Namazu Elements Community Edition
    • Common Issues with Docker
    • Unable to deploy application : dev.getelements.elements.sdk.exception.SdkElementNotFoundException
    • Running in the IDE
      • Exception in monitor thread while connecting to server localhost:27017
      • Could not deployAvailableApplications Jetty server Failed to bind to /0.0.0.0:8080 Address already in use

Releases

  • 3.6 Release Notes
  • 3.5 Release Notes
  • 3.4 Release Notes
  • 3.3 Release Notes
  • 3.2 Release Notes
  • 3.1 Release Notes
View Categories
  • Home
  • Docs
  • Your Game Code - Adding Custom Elements
  • RESTful APIs

RESTful APIs

Est. read time: 5 min read


How to build RESTful APIs in Elements #

Elements 3.0 Provides a complete implementation of Jakarta RESTful Web Services 4.0.0. 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 annotations 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:

  • Define the Element by annotating the package-info type in your code.
  • Add all compiled classes and jars into the Element package structure.
  • Expose the Application 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 #

{% code title=”package-info.java” %}

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

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

{% endcode %}

Step 2: Define the Application #

{% code title=”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
        );
    }

}

{% endcode %}

Step 3: Define the Endpoint Code #

{% code title=”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();

    }

}

{% endcode %}

Step 4: Ensure all Dependencies are Included #

{% code title=”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>

{% endcode %}

What are your Feelings
Still stuck? How can we help?

How can we help?

Updated on August 14, 2025
Custom Code OverviewWebsockets
Table of Contents
  • How to build RESTful APIs in Elements
  • Steps to Defining a Jakarta RS Element
    • Complete Example Code
      • Step 1: Define the Element
      • Step 2: Define the Application
      • Step 3: Define the Endpoint Code
      • Step 4: Ensure all Dependencies are Included
  • Documentation
  • Terms of Service
  • Privacy Policy
  • Contact us
  • Linkedin
  • Join our Discord

Namazu Studios LLC is powered by Namazu Elements, an Elemental Computing Inc. product.

Elements
  • Download
  • About Elements
  • Open source
  • Documentation
  • Support
About Namazu
  • Case Studies
  • About Us
  • News
Get in Touch
  • info@namazustudios.com
  • Book a call
  • (619) 862-2890
  • Linkedin
  • Discord

©2008-2025 Namazu Studios. All Rights Reserved.