All Projects → pileworx → akka-http-hal

pileworx / akka-http-hal

Licence: other
HAL (Hypermedia Application Language) specification support for akka-http

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to akka-http-hal

hal-api
Enhances your HATEOAS experience by automating common tasks.
Stars: ✭ 32 (+77.78%)
Mutual labels:  hal, hateoas
halfred
A parser for application/hal+json
Stars: ✭ 44 (+144.44%)
Mutual labels:  hypermedia, hal
jesi
Hypermedia API Accelerator
Stars: ✭ 19 (+5.56%)
Mutual labels:  hypermedia, hal
Pomona
A fruitful way to REST
Stars: ✭ 23 (+27.78%)
Mutual labels:  hypermedia, hateoas
react-ketting
Ketting bindings for React
Stars: ✭ 13 (-27.78%)
Mutual labels:  hypermedia, hateoas
Core
The server component of API Platform: hypermedia and GraphQL APIs in minutes
Stars: ✭ 2,004 (+11033.33%)
Mutual labels:  hypermedia, hal
reducio
❱ 🐇 URL shortener service is written in Scala using Akka-Http and Redis ❰
Stars: ✭ 69 (+283.33%)
Mutual labels:  akka-http
hal stm32
No description or website provided.
Stars: ✭ 56 (+211.11%)
Mutual labels:  hal
distributed-cache-on-k8s-poc
[PoC] Distributed Cache with Akka Cluster Sharding and Akka HTTP on Kubernetes
Stars: ✭ 15 (-16.67%)
Mutual labels:  akka-http
browser
A HAL browser middleware for node.js
Stars: ✭ 39 (+116.67%)
Mutual labels:  hal
Quark
Quark is a streaming-first Api Gateway using Akka
Stars: ✭ 13 (-27.78%)
Mutual labels:  akka-http
akka-cqrs-activator
Issue tracker PoC application written in Scala (Akka) and JavaScript (React) that demonstrates event sourcing and CQRS
Stars: ✭ 33 (+83.33%)
Mutual labels:  akka-http
akka-http-docker-sample
example of running an Sbt application in Docker based on openjdk:jre-alpine
Stars: ✭ 20 (+11.11%)
Mutual labels:  akka-http
restish
Restish is a CLI for interacting with REST-ish HTTP APIs with some nice features built-in
Stars: ✭ 453 (+2416.67%)
Mutual labels:  hypermedia
fdp-modelserver
An umbrella project for multiple implementations of model serving
Stars: ✭ 47 (+161.11%)
Mutual labels:  akka-http
akka-react-cloudant
A Soccer Dashboard created by scraping EPL website using Akka backend and ReactJS frontend and IBM Cloudant for object storage. IBM Cloud Foundry is used to host both frontend and backend app.
Stars: ✭ 21 (+16.67%)
Mutual labels:  akka-http
influencer-stats
Playground for measuring performance of functional programming tools in Scala. Gathers statistics about videos.
Stars: ✭ 24 (+33.33%)
Mutual labels:  akka-http
machinekit-hal
Universal framework for machine control based on Hardware Abstraction Layer principle
Stars: ✭ 89 (+394.44%)
Mutual labels:  hal
spring-batch-rest
REST API for Spring Batch using Spring Boot 2.2
Stars: ✭ 85 (+372.22%)
Mutual labels:  hateoas
php-serializer
Serialize PHP variables, including objects, in any format. Support to unserialize it too.
Stars: ✭ 47 (+161.11%)
Mutual labels:  hal

akka-http-hal

HAL Specification support library for akka-http.

Licensed under the Apache 2 license.

Build Status Codacy Badge Codacy Badge

Getting Started

Installation:

libraryDependencies += "io.pileworx" %% "akka-http-hal" % "1.2.5"

Support for Scala 2.11, 2.12, 2.13.

Usage

Create your marshaller:

trait FooProtocol extends DefaultJsonProtocol {
  implicit val fooFormat = jsonFormat3(FooDto)
}

You can import a collection of IANA Relations (Self, Next, etc):

import io.pileworx.akka.http.rest.hal.Relations._

Create a resource adapter:

trait FooAdapter extends FooProtocol {
  def fooLink(rel: String, id: String) = rel -> Link(href = s"/foos/$id")
  def foosLink(rel: String) = rel -> Link(href = "/foos")

  def newResource(id: String): JsValue = {
    ResourceBuilder(
      withLinks = Some(Map(
        fooLink(Self, id),
        foosLink(Up)
      ))
    ).build
  }

  def notFoundResource: JsValue = {
    ResourceBuilder(
      withLinks = Some(Map(contactsLink(Up)))
    ).build
  }

  def toResources(foos: Seq[FooDto]): JsValue = {
    ResourceBuilder(
      withEmbedded = Some(Map(
        "foos" -> foos.map(f => toResource(f))
      )),
      withLinks = Some(Map(foosLink(Self)))
    ).build
  }

  def toResource(foo: FooDto): JsValue = {
    ResourceBuilder(
      withData = Some(foo.toJson),
      withLinks = Some(Map(
        fooLink(Self, foo.id),
        foosLink(Up)
      ))
    ).build
  }
}

Create your routes:

trait FooRestPort extends FooAdapter {

  val fooService = new FooService with FooComponent

  val fooRoutes = path("foos") {
    get {
      complete {
        fooService.getAll.map(f => toResources(f))
      }
    } ~
    post {
      entity(as[CreateFooCommand]) { newFoo =>
        complete {
          Created -> fooService.add(newFoo).map(id => newResource(id))
        }
      }
    }
  } ~
  pathPrefix("foos" / Segment) { id =>
    get {
      complete {
        fooService.getById(id).map {
          case Some(f) => Marshal(toResource(f)).to[HttpResponse]
          case _ => Marshal(NotFound -> notFoundResource).to[HttpResponse]
        }
      }
    }
  }
}

Curies Support

Curies are supported in two ways.

The first is per resource:

ResourceBuilder(
  withCuries = Some(Seq(
    Curie(name = "ts", href = "http://typesafe.com/{rel}")
))).build

The second, and most likely more common way, is to set them globally:

ResourceBuilder.curies(Seq(
  Curie(name = "ts", href = "http://typesafe.com/{rel}"),
  Curie(name = "akka", href = "http://akka.io/{rel}")
))

Note: If you mix global and resource based curies they will be combined. Currently we do not check for duplicate entries.

For the links pointing to a curie, just prefix the key with the curie name and colon (ex "ts:info"). If a colon is found in a key, we do not alter the href by adding X-Forwarded data or the request host/port.

Array of Links Support

If you require an array of links:

{
  "_links": {
    "multiple_links": [
      {
        "href": "http://www.test.com?foo=bar",
        "name": "one"
      },
      {
        "href": "http://www.test.com?bar=baz",
        "name": "two"
      }
    ]
  }
}

This can be achieved by using the Links class which accepts a Sequence of Link:

Map(
  "multiple_links" -> Links(Seq(
    Link(href = url, name = Some("one")),
    Link(href = url, name = Some("two"))
)))

HttpRequest Support

By default the HAL links will not include the host or port.

If you would like host, port, or path prefix included, provide the HttpRequest.

def toResource(foo: FooDto, req: HttpRequest): JsValue = {
  ResourceBuilder(
    withRequest = req,
    withData = Some(foo.toJson),
    withLinks = Some(Map(
      fooLink("self", foo.id),
      foosLink("parent")
    ))
  ).build
}

This will produce a link with either the current host's information OR construct the links based on the X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Port, and X-Forwarded-Prefix headers.

HAL Browser

To expose HAL Browser from your API add the halBrowser route.

val routes = otherRoutes ~ halBrowserRoutes

The browser will be available at /halbrowser.

TODO

Find more contributors (hint).

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].