waratuman / elm-standardapi / StandardApi

Module for interfacing with StandardAPI.

For example you can make queries like the following:

--> "https://example.com/accounts?where[emails][eq]=e%40mail.com&limit=1"

Configuration


type alias Config =
{ url : Url
, headers : List ( String
, String )
, timeout : Maybe Basics.Float
, format : String
, version : String 
}

StandardAPI configuration.

Schema


type alias Schema =
{ comment : String
, models : List Model
, routes : List Route 
}

A StandardAPI schema definition.


type alias Route =
{ path : String
, method : String
, model : Maybe Model
, array : Basics.Bool
, limit : Maybe Basics.Int
, wheres : List Attribute
, orders : List String
, includes : List (Tree String) 
}

A StandardAPI route definition.


type alias Model =
{ name : String
, attributes : List Attribute
, comment : String 
}

A StandardAPI model definition.


type alias Attribute =
{ name : String
, type_ : String
, default : Maybe String
, primaryKey : Basics.Bool
, null : Basics.Bool
, array : Basics.Bool
, comment : String 
}

A StandardAPI attribute definition.

schemaRequest : Config -> { msg : Result Error Schema -> msg, tracker : Maybe String } -> Platform.Cmd.Cmd msg

Request the Schema from a StandardAPI resource.

schemaRequestTask : Config -> Task Error Schema

Just like schemaRequest, but it creates a Task.

Requests


type Error
    = BadUrl String
    | Timeout
    | NetworkError
    | BadStatus Basics.Int String
    | BadBody String

Error responses.

errorToString : Error -> String

Convert a Error into a String that is nice for debugging.

request : Config -> { method : String, headers : List Http.Header, path : String, body : Http.Body, expect : Http.Expect msg, tracker : Maybe String } -> Platform.Cmd.Cmd msg

Create a HTTP request to a StandardAPI enpoint.

import Url exposing (Protocol(..))

config =
    { url =
        { protocol = Https
        , host = "example.com"
        , port_ = Nothing
        , path = ""
        , query = Nothing
        , fragment = Nothing
        }
    , headers = [ ( "Api-Key", "token") ]
    , timeout = Just 20
    , format = "application/json"
    , version = "0.1.0"
    }

request config
    { method = "GET"
    , headers = []
    , path = "/posts"
    , body = emptyBody
    , msg = ReceivedPosts
    , decoder = list postDecoder
    , tracker = Nothing
    }

requestTask : Config -> { method : String, headers : List Http.Header, path : String, body : Http.Body, resolver : Http.Resolver Error a } -> Task Error a

Just like request, but it creates a Task.

cancel : String -> Platform.Cmd.Cmd msg

Try to cancel an ongoing request based on a tracker.

Body

emptyBody : Http.Body

An empty body for a request. This is simply an alias for Http.emptyBody so you don't need to import Http.

jsonBody : Json.Encode.Value -> Http.Body

Put a JSON value in the body of the request. This is simply an alias for Http.jsonBody so you don't need to import Http.

Expect

expectJson : (Result Error a -> msg) -> Json.Decode.Decoder a -> Http.Expect msg

Just like Http.expectJson, but for decoding a JSON value in StandardAPI.

expectWhatever : (Result Error () -> msg) -> Http.Expect msg

Just like Http.expectWhatever, but for decoding a JSON value in StandardAPI.

jsonResolver : Json.Decode.Decoder a -> Http.Resolver Error a

Just like Http.stringResolver, but for decoding a JSON value.

Querying


type alias Query =
{ limit : Limit
, order : Order
, offset : Offset
, predicate : Maybe Operation
, includes : List (Tree Include) 
}

A Query is used to make a request against the server. This is similar to a SQL query.


type Operation
    = Ilike (List String) Value
    | In (List String) (List Value)
    | NotIn (List String) (List Value)
    | Lt (List String) Value
    | Lte (List String) Value
    | Eq (List String) Value
    | Gt (List String) Value
    | Gte (List String) Value
    | Null (List String)
    | Set (List String)
    | Overlaps (List String) (List Value)
    | Contains (List String) Value
    | Conjunction Operation Operation
    | Disjunction Operation Operation

The Operation type is used for making comparisons in a predicate.


type Direction
    = Asc
    | Desc

The Direction type is used to order a query.


type alias Limit =
Maybe Basics.Int

The Limit type for limiting the results of a query. If the value is Nothing, the default value is used (which may be unlimited). If the value is a Just x, then the limit will be x.


type alias Offset =
Maybe Basics.Int

The Offset type is for offseting the results of a query. If the value is Nothing, there will be no offset (the same as Just 0). If the value is a Just x, then the offset will be x.


type alias Order =
List ( String
, Direction 
}

The Order type is used to order a query. It is represented as a list containing a tuple with the name of the colum and the direction to order.


type Value
    = Int Basics.Int
    | String String
    | Float Basics.Float
    | Bool Basics.Bool
    | Posix Time.Posix
    | Dict (Dict String Value)

A Value is used for making comparisons. In the example x > 3, 3 is the value.


type Include
    = Include (( String, Query ))

The Include type is for including related results in a query. For example, in the query { emptyQuery | includes = [ include ( "line_items", emptyQuery ) ] would include related line_items in the response.

emptyQuery : Query

An empty query.

include : ( String, Query ) -> Include

Helper method to generate an include.

import StandardApi exposing (..)

include ("users", { emptyQuery | limit = Just 1 })
--> Include ("users", { emptyQuery | limit = Just 1 })

unwrapInclude : Include -> ( String, Query )

Helper method to unwrap and include into the name of the include and its subinclude. This is necessary due to recursion in the types.

import StandardApi exposing (..)

unwrapInclude (include ("users", { emptyQuery | limit = Just 1 }))
--> ("users", { emptyQuery | limit = Just 1 })

Url generation

Url parsing