LogoLogo
Studio
4.6
4.6
  • Harper Docs
  • Getting Started
    • What is Harper
    • Install Harper
    • Harper Concepts
    • Create Your First Application
  • Developers
    • Applications
      • Caching
      • Defining Schemas
      • Defining Roles
      • Data Loader
      • Debugging Applications
      • Define Fastify Routes
      • Web Applications
      • Example Projects
    • Components
      • Managing
      • Reference
      • Built-In Components
    • REST
    • Operations API
      • Quick Start Examples
      • Databases and Tables
      • NoSQL Operations
      • Bulk Operations
      • Users and Roles
      • Clustering
        • Clustering with NATS
      • Components
      • Registration
      • Jobs
      • Logs
      • System Operations
      • Configuration
      • Certificate Management
      • Token Authentication
      • SQL Operations
      • Advanced JSON SQL Examples
    • Real-Time
    • Replication/Clustering
      • Sharding
      • Legacy NATS Clustering
        • Requirements and Definitions
        • Creating A Cluster User
        • Naming A Node
        • Enabling Clustering
        • Establishing Routes
        • Subscription Overview
        • Managing Subscriptions
        • Things Worth Knowing
        • Certificate Management
    • Security
      • JWT Authentication
      • Basic Authentication
      • mTLS Authentication
      • Configuration
      • Users & Roles
      • Certificate Management
    • SQL Guide
      • SQL Features Matrix
      • SQL Date Functions
      • SQL Reserved Word
      • SQL Functions
      • SQL JSON Search
      • SQL Geospatial Functions
    • Miscellaneous
      • Google Data Studio
      • SDKs
      • Query Optimization
  • Administration
    • Best Practices and Recommendations
    • Logging
      • Standard Logging
      • Audit Logging
      • Transaction Logging
    • Clone Node
    • Compact
    • Jobs
    • Harper Studio
      • Create an Account
      • Log In & Password Reset
      • Organizations
      • Instances
      • Query Instance Data
      • Manage Databases / Browse Data
      • Manage Clustering
      • Manage Instance Users
      • Manage Instance Roles
      • Manage Applications
      • Instance Metrics
      • Instance Configuration
      • Enable Mixed Content
  • Deployments
    • Configuration File
    • Harper CLI
    • Install Harper
      • On Linux
    • Upgrade a Harper Instance
    • Harper Cloud
      • IOPS Impact on Performance
      • Instance Size Hardware Specs
      • Alarms
      • Verizon 5G Wavelength
  • Technical Details
    • Reference
      • Analytics
      • Architecture
      • Content Types
      • Data Types
      • Dynamic Schema
      • GraphQL
      • Harper Headers
      • Harper Limits
      • Globals
      • Resource Class
      • Transactions
      • Storage Algorithm
      • Blob
    • Release Notes
      • Harper Tucker (Version 4)
        • 4.6.0
        • 4.5.10
        • 4.5.9
        • 4.5.8
        • 4.5.7
        • 4.5.6
        • 4.5.5
        • 4.5.4
        • 4.5.3
        • 4.5.2
        • 4.5.1
        • 4.5.0
        • 4.4.24
        • 4.4.23
        • 4.4.22
        • 4.4.21
        • 4.4.20
        • 4.4.19
        • 4.4.18
        • 4.4.17
        • 4.4.16
        • 4.4.15
        • 4.4.14
        • 4.4.13
        • 4.4.12
        • 4.4.11
        • 4.4.10
        • 4.4.9
        • 4.4.8
        • 4.4.7
        • 4.4.6
        • 4.4.5
        • 4.4.4
        • 4.4.3
        • 4.4.2
        • 4.4.1
        • 4.4.0
        • 4.3.38
        • 4.3.37
        • 4.3.36
        • 4.3.35
        • 4.3.34
        • 4.3.33
        • 4.3.32
        • 4.3.31
        • 4.3.30
        • 4.3.29
        • 4.3.28
        • 4.3.27
        • 4.3.26
        • 4.3.25
        • 4.3.24
        • 4.3.23
        • 4.3.22
        • 4.3.21
        • 4.3.20
        • 4.3.19
        • 4.3.18
        • 4.3.17
        • 4.3.16
        • 4.3.15
        • 4.3.14
        • 4.3.13
        • 4.3.12
        • 4.3.11
        • 4.3.10
        • 4.3.9
        • 4.3.8
        • 4.3.7
        • 4.3.6
        • 4.3.5
        • 4.3.4
        • 4.3.3
        • 4.3.2
        • 4.3.1
        • 4.3.0
        • 4.2.8
        • 4.2.7
        • 4.2.6
        • 4.2.5
        • 4.2.4
        • 4.2.3
        • 4.2.2
        • 4.2.1
        • 4.2.0
        • 4.1.2
        • 4.1.1
        • 4.1.0
        • 4.0.7
        • 4.0.6
        • 4.0.5
        • 4.0.4
        • 4.0.3
        • 4.0.2
        • 4.0.1
        • 4.0.0
        • Tucker
      • HarperDB Monkey (Version 3)
        • 3.3.0
        • 3.2.1
        • 3.2.0
        • 3.1.5
        • 3.1.4
        • 3.1.3
        • 3.1.2
        • 3.1.1
        • 3.1.0
        • 3.0.0
      • HarperDB Penny (Version 2)
        • 2.3.1
        • 2.3.0
        • 2.2.3
        • 2.2.2
        • 2.2.0
        • 2.1.1
      • HarperDB Alby (Version 1)
        • 1.3.1
        • 1.3.0
        • 1.2.0
        • 1.1.0
  • More Help
    • Support
    • Slack
    • Contact Us
Powered by GitBook
On this page
  • Setup Your Project
  • Creating our first Table
  • Adding Attributes to our Table
  • Adding an Endpoint
  • Authenticating Endpoints
  • Content Negotiation
  • Querying
  • Key Takeaway
  1. Getting Started

Create Your First Application

PreviousHarper ConceptsNextApplications

Last updated 2 days ago

Now that you've set up Harper, let's build a simple API. Harper lets you build powerful APIs with minimal effort. In just a few minutes, you'll have a functional REST API with automatic validation, indexing, and querying—all without writing a single line of code.

Setup Your Project

Start by cloning the Harper application template:

git clone https://github.com/HarperDB/application-template my-app
cd my-app

Creating our first Table

The core of a Harper application is the database, so let's create a database table.

A quick and expressive way to define a table is through a . Using your editor of choice, edit the file named schema.graphql in the root of the application directory, my-app, that we created above. To create a table, we will need to add a type of @table named Dog (and you can remove the example table in the template):

type Dog @table {
	# properties will go here soon
}

And then we'll add a primary key named id of type ID:

(Note: A GraphQL schema is a fast method to define tables in Harper, but you are by no means required to use GraphQL to query your application, nor should you necessarily do so)

type Dog @table {
	id: ID @primaryKey
}

Now we tell Harper to run this as an application:

harperdb dev . # tell Harper cli to run current directory as an application in dev mode

Harper will now create the Dog table and its id attribute we just defined. Not only is this an easy way to create a table, but this schema is included in our application, which will ensure that this table exists wherever we deploy this application (to any Harper instance).

Adding Attributes to our Table

Next, let's expand our Dog table by adding additional typed attributes for dog name, breed and age.

type Dog @table {
	id: ID @primaryKey
	name: String
	breed: String
	age: Int
}

This will ensure that new records must have these properties with these types.

Because we ran harperdb dev . earlier (dev mode), Harper is now monitoring the contents of our application directory for changes and reloading when they occur. This means that once we save our schema file with these new attributes, Harper will automatically reload our application, read my-app/schema.graphql and update the Dog table and attributes we just defined. The dev mode will also ensure that any logging or errors are immediately displayed in the console (rather only in the log file).

As a document database, Harper supports heterogeneous records, so you can freely specify additional properties on any record. If you do want to restrict the records to only defined properties, you can always do that by adding the sealed directive:

type Dog @table @sealed {
	id: ID @primaryKey
	name: String
	breed: String
	age: Int
	tricks: [String]
}

Adding an Endpoint

Now that we have a running application with a database (with data if you imported any data), let's make this data accessible from a RESTful URL by adding an endpoint. To do this, we simply add the @export directive to our Dog table:

type Dog @table @export {
	id: ID @primaryKey
	name: String
	breed: String
	age: Int
	tricks: [String]
}
POST /Dog/
Content-Type: application/json

{
	"name": "Harper",
	"breed": "Labrador",
	"age": 3,
	"tricks": ["sits"]
}

With this a record will be created and the auto-assigned id will be available through the Location header. If you added a record, you can visit the path /Dog/<id> to view that record. Alternately, the curl command curl http://localhost:9926/Dog/<id> will achieve the same thing.

Authenticating Endpoints

Now that you've created your first API endpoints, it's important to ensure they're protected. Without authentication, anyone could potentially access, misuse, or overload your APIs, whether by accident or malicious intent. Authentication verifies who is making the request and enables you to control access based on identity, roles, or permissions. It’s a foundational step in building secure, reliable applications.

Content Negotiation

These endpoints support various content types, including JSON, CBOR, MessagePack and CSV. Simply include an Accept header in your requests with the preferred content type. We recommend CBOR as a compact, efficient encoding with rich data types, but JSON is familiar and great for web application development, and CSV can be useful for exporting data to spreadsheets or other processing.

Harper works with other important standard HTTP headers as well, and these endpoints are even capable of caching interaction:

Authorization: Basic <base64 encoded user:pass>
Accept: application/cbor
If-None-Match: "etag-id" # browsers can automatically provide this

Querying

In order to maintain reasonable query speed on a database as it grows in size, it is critical to select and establish the proper indexes. So, before we add the @export declaration to our Dog table and begin querying it, let's take a moment to target some table properties for indexing. We'll use name and breed as indexed table properties on our Dog table. All we need to do to accomplish this is tag these properties with the @indexed directive:

type Dog @table {
  id: ID @primaryKey
  name: String @indexed
  breed: String @indexed
  owner: String
  age: Int
  tricks: [String]
}

And finally, we'll add the @export directive to expose the table as a RESTful endpoint

type Dog @table @export {
	id: ID @primaryKey
	name: String @indexed
	breed: String @indexed
	owner: String
	age: Int
	tricks: [String]
}

Now we can start querying. Again, we just simply access the endpoint with query parameters (basic GET requests), like:

http://localhost:9926/Dog/?name=Harper
http://localhost:9926/Dog/?breed=Labrador
http://localhost:9926/Dog/?breed=Husky&name=Balto&select(id,name,breed)

Key Takeaway

Harper's schema-driven approach means you can build production-ready APIs in minutes, not hours. Start with pure schema definitions to get 90% of your functionality, then add custom code only where needed. This gives you the best of both worlds: rapid development with the flexibility to customize when required.

By default the application HTTP server port is 9926 (this can be ), so the local URL would be http://localhost:9926/Dog/ with a full REST API. We can PUT or POST data into this table using this new path, and then GET or DELETE from it as well (you can even view data directly from the browser). If you have not added any records yet, we could use a PUT or POST to add a record. PUT is appropriate if you know the id, and POST can be used to assign an id:

Endpoints created with Harper automatically support Basic, Cookie, and JWT authentication methods. See the documentation on for more information on different levels of access.

By default, Harper also automatically authorizes all requests from loopback IP addresses (from the same computer) as the superuser, to make it simple to interact for local development. If you want to test authentication/authorization, or enforce stricter security, you may want to disable the .

Querying your application database is straightforward and easy, as tables exported with the @export directive are automatically exposed via . Simple queries can be crafted through .

Congratulations, you now have created a secure database application backend with a table, a well-defined structure, access controls, and a functional REST endpoint with query capabilities! See the and see the for more options for defining schemas.

Additionally, you may now use GraphQL (over HTTP) to create queries. See the documentation for that new feature .

GraphQL Schema
security
REST endpoints
URL query parameters
REST documentation for more information on HTTP access
Schema reference
here
configured here
authentication.authorizeLocal setting