endpoints-elm


License

License

Categories

Categories

Scala Languages
GroupId

GroupId

io.scalaland
ArtifactId

ArtifactId

endpoints-elm_2.12
Last Version

Last Version

0.10.0
Release Date

Release Date

Type

Type

jar
Description

Description

endpoints-elm
endpoints-elm
Project URL

Project URL

https://github.com/scalalandio
Project Organization

Project Organization

io.scalaland
Source Code Management

Source Code Management

https://github.com/scalalandio/endpoints-elm

Download endpoints-elm_2.12

How to add to project

<!-- https://jarcasting.com/artifacts/io.scalaland/endpoints-elm_2.12/ -->
<dependency>
    <groupId>io.scalaland</groupId>
    <artifactId>endpoints-elm_2.12</artifactId>
    <version>0.10.0</version>
</dependency>
// https://jarcasting.com/artifacts/io.scalaland/endpoints-elm_2.12/
implementation 'io.scalaland:endpoints-elm_2.12:0.10.0'
// https://jarcasting.com/artifacts/io.scalaland/endpoints-elm_2.12/
implementation ("io.scalaland:endpoints-elm_2.12:0.10.0")
'io.scalaland:endpoints-elm_2.12:jar:0.10.0'
<dependency org="io.scalaland" name="endpoints-elm_2.12" rev="0.10.0">
  <artifact name="endpoints-elm_2.12" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.scalaland', module='endpoints-elm_2.12', version='0.10.0')
)
libraryDependencies += "io.scalaland" % "endpoints-elm_2.12" % "0.10.0"
[io.scalaland/endpoints-elm_2.12 "0.10.0"]

Dependencies

compile (1)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.12.8

provided (2)

Group / Artifact Type Version
org.julienrf : endpoints-algebra_2.12 jar 0.10.0
org.julienrf : endpoints-algebra-json-schema_2.12 jar 0.10.0

test (2)

Group / Artifact Type Version
com.lihaoyi : utest_2.12 jar 0.7.1
io.scalaland : endpoints-json-schema-macros_2.12 jar 0.10.0

Project Modules

There are no modules declared in this project.

endpoints-elm

Build Status Maven Central License

Elm code generator based on Scala endpoints library.

New to endpoints?

Endpoints is great Scala library that allows you to define communication protocols over HTTP and keep consistent server implementation, clients and documentation. See also official project documentation

Elm code generator

This project provides:

  • interpreter for all basic endpoints algebras that targets data structures that resemble elm type system
  • code emitter that takes these data structures and emits elm code containing:
    • elm type definitions
    • json encoders and decoders
    • init value providers
    • url construction methods targeting elm-url
    • api client methods targeting elm-http-builder
Output code structure
Data/Type1.elm
Data/Type2.elm
Data/Type3.elm
Request/Url/HttpModule1.elm
Request/Url/HttpModule2.elm
Request/Url/HttpModule3.elm
Request/HttpModule1.elm
Request/HttpModule2.elm
Request/HttpModule3.elm

Getting started

To get started, first add project dependency to your build.sbt:

libraryDependencies += "io.scalaland" %% "endpoints-elm" % "0.10.0"
Endpoints definition

If you follow endpoints quick start guide, you end up with something similar to:

import endpoints.{algebra, generic}

case class Counter(value: Int)
case class Increment(step: Int)

trait CounterEndpoints
    extends algebra.Endpoints
    with algebra.JsonSchemaEntities
    with algebra.JsonSchemas
    with generic.JsonSchemas {

  implicit lazy val counterSchema: JsonSchema[Counter] = named(genericJsonSchema[Counter], "Counter")
  implicit lazy val incrementSchema: JsonSchema[Increment] = named(genericJsonSchema[Increment], "Increment")
  
  val currentValue: Endpoint[Unit, Counter] =
    endpoint(
      get(path / "current-value"),
      jsonResponse[Counter](docs = Some("Coutner status")),
      tags = List("Counter")
    )

  val increment: Endpoint[Increment, Unit] =
    endpoint(
      post(path / "increment", jsonRequest[Increment](docs = Some("Counter increment request"))),
      emptyResponse(),
      tags = List("Counter")
    )
}

For code generation purposes it's required to:

  • name your json schemas for types using named(schema, "YourSchemaName")
  • tag your endpoints using tags = List("YourEndpointTag")

Type and file names in generated code is based on those names.

Mixing code generator interpreter

Then you need to mix in io.scalaland.endpoints.elm.ElmCodeGenerator with your endpoints trait.

import io.scalaland.endpoints.elm.ElmCodeGenerator

object ElmCounterGen extends CounterEndpoints with ElmCodeGenerator {

    def generateCode(): Unit = {
      writeElmCode("target/directory")(currentValue, increment)()    
    }
}

Invoking ElmCounterGen.generateCode() will clean target directory, create Data and Request directories and write down elm modules for data types and http api client.

Codegen target

Generated code consists of bunch of modules of 2 kinds: data modules and http request modules.

Data modules

Example data module looks like follows:

{-
  This file was generated by endpoints-elm interpreter.
  Do not edit this file manually.

  See https://github.com/scalalandio/endpoints-elm for more information.
-}

module Data.Counter exposing (..)


import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional, required)
import Json.Encode as Encode


type alias Counter = 
  { value : Int
  }

init : Counter
init = 
  { value = 0
  }

decoder : Decoder Counter
decoder = Decode.succeed Counter
  |> required "value" Decode.int 

encoder : Counter -> Encode.Value
encoder model = Encode.object (fieldsEncoder model)

encoderTagged : (String, String) -> Counter -> Encode.Value
encoderTagged (discriminator, tag) model = Encode.object ((discriminator, Encode.string tag) :: fieldsEncoder model)

fieldsEncoder : Counter -> List (String, Encode.Value)
fieldsEncoder model = 
  [ ( "value", Encode.int model.value )
  ]

setValue : Int -> Counter -> Counter
setValue newValue counter =
  { counter | value = newValue }

updateValue : (Int -> Int) -> Counter -> Counter
updateValue f counter =
  { counter | value = f counter.value }

It contains:

  • type definition (type alias Counter)
  • initial/example value definition (init)
  • Json codecs (decoder and encoder)
  • utility functions for setting fields to a specific value (setValue)
  • utility functions for updating fields using provided function (updateValue)
Url modules

Module with urls contains one function that constructs url string for each endpoint.

{-
   This file was generated by endpoints-elm 0.10.0 interpreter.
   Do not edit this file manually.

   See https://github.com/scalalandio/endpoints-elm for more information.
-}


module Request.Url.Counter exposing (currentvalueGet, incrementPost)

import Bool.Extra
import Maybe.Extra
import Url.Builder


currentvalueGet : String
currentvalueGet =
    Url.Builder.relative
        [ "/", "current-value" ]
        []


incrementPost : String
incrementPost =
    Url.Builder.relative
        [ "/", "increment" ]
        []
Http modules

Http module utilizes generated url module and for each endpoint contains a function that returns HttpBuilder.Task.RequestBuilder.

{-
   This file was generated by endpoints-elm 0.10.0 interpreter.
   Do not edit this file manually.

   See https://github.com/scalalandio/endpoints-elm for more information.
-}


module Request.Counter exposing (currentvalueGet, incrementPost)

import Request.Url.Counter
import EndpointsElm
import Http
import HttpBuilder.Task exposing (RequestBuilder)
import Json.Decode as Decode
import Json.Encode as Encode
import Bool.Extra
import Maybe.Extra
import Bytes exposing (Bytes)
import Dict exposing (Dict)

import Data.Counter exposing (..)
import Data.Increment exposing (..)


currentvalueGet : RequestBuilder Http.Error Counter
currentvalueGet  =
  HttpBuilder.Task.get (Request.Url.Counter.currentvalueGet )
    |> HttpBuilder.Task.withResolver (Http.stringResolver (EndpointsElm.httpResolveJson (Data.Counter.decoder)))
    |> HttpBuilder.Task.withTimeout 30000


incrementPost : Increment -> RequestBuilder Http.Error ()
incrementPost increment =
  HttpBuilder.Task.post (Request.Url.Counter.incrementPost )
    |> HttpBuilder.Task.withBody (Http.jsonBody (Data.Increment.encoder increment))
    |> HttpBuilder.Task.withResolver (Http.stringResolver (EndpointsElm.httpResolveUnit))
    |> HttpBuilder.Task.withTimeout 30000
Dependencies

Code generation in endpoints-elm makes some assumptions about dependencies in elm project.

You need to have installed following packages:

"Chadtech/elm-bool-extra": "2.4.0"
"NoRedInk/elm-json-decode-pipeline": "1.0.0"
"elm/core": "1.0.2"
"elm/http": "2.0.0"
"elm/json": "1.1.3"
"elm-community/maybe-extra": "5.0.0",
"elm/url": "1.0.0",
"elm/bytes": "1.0.8",
"lukewestby/elm-http-builder": "7.0.0"

For elm/http 1.0.0 and lukewestby/elm-http-builder 6.0.0, check out version 0.9.1 of this library.

See also exampleout/elm.json.

Customizing code generation

TBD

io.scalaland

Scalaland.io

We have another fantastic day writing Scala

Versions

Version
0.10.0
0.9.2
0.9.1
0.9.0