Giter Site home page Giter Site logo

sassoftware / unravl Goto Github PK

View Code? Open in Web Editor NEW
17.0 9.0 6.0 1.13 MB

UnRAVL is a domain-specific language for testing REST APIs. It is specification-driven and encoded in JSON, which allows easy test case generation from other tools and directly embedded JSON request bodies or comparing results to expected JSON test data. UnRAVL contains a number of useful assertion constructs for validating REST API calls.

License: Apache License 2.0

Java 99.06% Batchfile 0.32% Shell 0.62%

unravl's Introduction

unravl has been archived!

This project is no longer actively maintained by its owner, so we have set the project as read-only (archive). If you continue to use it, be advised that its dependencies (referenced in pom.xml) may require attention as there are often security-related updates. If you find the project useful and would like to bring it forward, please feel free to fork the repo!

Uniform REST API Validation Language (UnRAVL) - a JSON domain-specific language for validating REST APIs

UnRAVL is a domain-specific language, coded in JSON, for validating REST APIs. UnRAVL scripts consist of a JSON description of a REST API call:

  1. HTTP method
  2. URI
  3. HTTP headers (optional)
  4. Request body (optional)
  5. Authentication (optional)

For each API call, an UnRAVL script may also contain assertions which validate the results. You can assert:

  1. The result body matches expected JSON, text or other data
  2. Specific headers exist with specific values
  3. HTTP status code is a specific value or is in a specific set

UnRAVL also supports extracting data from a REST API call's results and using those values for assertions or in future API calls.

A template facility provides reusable API call and validation constructs.

Although initially conceived as a REST validation tool, UnRAVL is also well-suited for use as a REST scripting language, for stringing together a set of interrelated REST calls, extracting results and headers from early calls to be used when making subsequent calls. Users may find it useful to associate .unravl files with the UnRAVL jar file via the batch scripts in the src/main/bin directory so you can run scripts from your file explorer.

UnRAVL was designed and initially implemented by David Biesack @DavidBiesack (GitHub) @DavidBiesack (Twitter). unRAVL is an implementation of API validation system, U.S. Patent No. 9,552,237.

A basic REST validation

The most fundamental form of validation is to invoke an API and validate the response code and response body.

Let's consider the REST call

 GET  http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false

This can be captured in JSON using the UnRAVL syntax

{ "GET" : "http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false" }

This is a fully functioning UnRAVL script. Besides executing the call, UnRAVL will also validate that the call returns a 2xx level HTTP status code, indicating success in one form or another.

However, that is not highly useful. This particular REST call should return the JSON body:

{
   "results" : [
      {
         "elevation" : 8815.7158203125,
         "location" : {
            "lat" : 27.988056,
            "lng" : 86.92527800000001
         },
         "resolution" : 152.7032318115234
      }
   ],
   "status" : "OK"
}

UnRAVL scripts are JSON documents that encode the call, response, and assertions. This is useful since much of the test data (request bodies, responses) will be JSON.

Below is an UnRAVL script that performs the above REST call, asserts the result matches the expected JSON and that the HTTP response is 200:

{
  "name" : "GoogleEverestElevation",
  "GET" : "http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false",
  "assert": [
    { "status" : 200 },
    { "json" :

{ "results" : [ { "elevation" : 8815.7158203125,
        "location" : { "lat" : 27.988056,
            "lng" : 86.92527800000001
          },
        "resolution" : 152.7032318115234
      } ],
  "status" : "OK"
}
     }
  ]
}

This shows invoking an API using the GET method. "GET", "HEAD", "POST", "PUT", "DELETE", "PATCH" are the allowed HTTP verbs. For POST, PUT and PATCH, you can also pass a request body.

Next, we verify the result with a set of assertions:

  1. the expected HTTP status code, 200 OK ; the value could also be an array of allowed response types, such as [200, 204] or a string value which is a regular expression, such as "2.." If a "status" assertion is omitted, the status code must match "2.."; that is, be a 200-level status code.
  2. assert the JSON body matches an expected JSON structure.

The simplest response body assertion is a literal assertion that the body matches the expected JSON, although admittedly this is somewhat fragile. The implementation of such benchmark comparison assertions performs a structural comparison and allows for different order of items in JSON objects, as well as whitespace differences.

Another form of response assertion allows comparing the received body to the contents of a benchmark file rather than literal JSON in the file. (In the JSON based DSL, this form is required for XML benchamrks.)

{
  "name" : "GoogleEverestElevation",
  "GET" : "http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false",
  "assert": [
    { "status" : 200 },
    { "json" :  "@{benchmarks}/{name}.json" }
    ]
}

The @ notation indicates the JSON is located at a file or URL, not in line. This example expects two variables to be bound in the UnRAVL environment: benchmarks is the name of a directory containing JSON files. name is the current test name (set by the "name" element of the script), with the value "GoogleEverestElevation" in this case. The {varName} notation is used to evaluate the value of an environment variable. More on this later.

However, because representation assertions are fragile, an alternate approach would be to perform more specific assertions for data elements in the body.

{
  "name" : "GoogleEverestElevation",
  "GET" : "http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false",
  "bind" : { "json" : "response" },
  "assert": [
     "response.results[0].elevation.doubleValue() == 8815.7158203125",
     "response.results[0].location.lat.doubleValue() == 27.988056",
     "response.results[0].location.lng.doubleValue() == 86.925278",
     "response.status.textValue().equals('OK')"
    ]
}

UnRAVL scripts also have an environment, which is a set of name/value pairs or variables. You can set variables explicitly, or bind them based on the result of API calls. For example, the above binds the JSON response body to a JsonNode (using the Jackson library for JSON) named response. (See "json" for details.) This variable may be used to compare nested values, as seen in the assert array. Each assertion string is a Groovy expression that must evaluate to true for the test to pass. (You can also use JavaScript.) Groovy expressions can walk JSON structures naturally by accessing object values by name, or array items by index. The doubleValue() method extracts the numeric value of a Jackson NumericNode item.

Most string values in UnRAVL scripts are subject to environment substitution which replaces substrings of the form {varName} with the value of the named variable from the environment.

Syntax and reference

To see the full syntax for UnRAVL scripts, refer to Reference.

Interactive mode

UnRAVL provides a simple interactive interface for running scripts. See Interactive mode for details.

Releases

See Releases

Running UnRAVL

You can download the source from this repo and run

    git clone [email protected]:sassoftware/unravl.git
    cd unravl
    ./gradlew clean build copyDeps

Run UnRAVL as:

    src/main/bin/unravl.sh src/test/scripts/hello.json  # from Linux or Mac OS X
    src\main\bin\unravl.bat src\test\scripts\hello.json # from Windows

Alternatively, you can download the binary release. Create a directory unravl for your local copy of UnRAVL, cd unravl to that directory, then download a release. Unzip the release file in the unravl directory. Run UnRAVL using the scripts in the bin directory, as described above. (In the binary distribution the scripts are in bin not src/main/bin.)

When integrated into a Java application, you may run UnRAVL scripts by instantiating an UnRAVLRuntime object, then creating an UnRAVL object based on a Jackson ObjectNode or ArrayNode, then invoking the run() method.

import com.sas.unravl.UnRAVL;
import com.sas.unravl.UnRAVLRuntime;
import com.sas.unravl.ApiCall;
import com.sas.unravl.util.Json;
...
  UnRAVLRuntime runtime = new UnRAVLRuntime();
  UnRAVL unravl = new UnRAVL(runtime, objectNode);
  ApiCall call = unravl.run();

The UnRAVLRuntime contains the environment variables and may be reused to run multiple UnRAVL instances.

Contributing

Contributors are welcome to join the project. See ContributorAgreement.txt.

To contribute, submit issues for bugs or enhancments. Fork this repo, then clone your GitHub fork:

$ git clone [email protected]:userid/unravl.git

(Change userid to your GutHub user id). Next, set the Git upstream which will allow you to merge from master:

$ cd unravl
$ git remote add upstream [email protected]:sassoftware/unravl.git

Before doing local development, be sure to sync your local code:

To sync your fork with master after changes have been merged at https://github.com/sassoftware/unravl :

$ cd unravl # change to your local clone
$ git fetch upstream # get all branches
$ git checkout master
$ git merge upstream/master

Create a local branch for your changes, then push to your personal unravl repo and create a GitHub pull request for submitting new contributions.

Contributions should use the Eclipse format configuration in eclipse-java-format.xml and organize imports in com, java, javax, org order (alphabetical, with grouping)

Contributors are listed in CONTRIBUTORS.md.

License

UnRAVL is released under the Apache 2.0 License.

unravl's People

Contributors

cjdinger avatar davidbiesack avatar oksanakoziaryk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unravl's Issues

add "links" assertion to compare link objects to expected JSON

Add a new "links" assertion which extracts links like the current "links" bind element,
but also asserts those links contain the JSON literal data.

  "env"  : { "deleteLink" :  { "rel" : "delete", "method" : "DELETE", "uri" "{location}" },
  "assert" : { "links" : {
            "self" : { "rel" : "self", 
                         "method" : "GET", 
                         "uri" "{location}", 
                         "type" : "application/vnd.sas.my.type" },
            "delete" : "deleteLink"
             } }

This would be equivalent to the more verbose

   "env"  : { "deleteLink" :  { "rel" : "delete", "method" : "DELETE", "uri" "{location}" },
   "bind" : { "links" : [ "self", "delete" ] },
   "assert" : [
          "self.rel.textValue() == 'self'",
          "self.method.textValue() == 'GET",
          "self.uri.textValue() == '{location}'",
          "self.type.textValue() == 'application/vnd.sas.my.type'",
          "delete == {deleteLink}"
    ]

Currently, "link" can extract links, but assertions are complex because UnRAVL
does not provide a way to assert that a JSON object contains some other JSON;
we can only assert JSON equality. See also Issue #21 . If that were implemented,
this request is less important; one could use a "link" extractor and a "json" assertion:

  "env"  : { "deleteLink" :  { "rel" : "delete", "method" : "DELETE", "uri" "{location}" },
  "bind" : { "links" : "self" },
  "assert" : { "json" : {
                "self" : { "rel" : "self", 
                             "method" : "GET", 
                             "uri" "{location}", 
                             "type" : "application/vnd.sas.my.type" },
                "delete" : "deleteLink"
                 },
                 "contains" : true }

Change stdout to JSON or YAML format

The output is plain text and not easily parsed. Change to JSON or JAML so that it is structured yet still easy to read.

Seeking input on how useful this would be.

oauth2 authentication ignores client/secret

If you use the clientId and clientSecret in an

    "auth" : {"oath2" : host, ...  "user" : "userid-string", "password" : "password-string"} 

object, an embedded clientId/clientSecret pair is ignored, or if clientid/secret exist in the .netrc file, they are not read.

Add "expect" and/or "response" as an alias for "assert"

Some users may prefer to use "expect" instead of "assert". This helps with readability, especially when using UnRAVL scripts to document* REST APIs with working examples.

{  "POST" : "http://www.example.com/myApi/myResource",
   "headers" : { "Content-Type" : "application-json",
                 "Accept" : "application-json"  },
   "body" : { "name" : "GitHub", "description" : "Open Source repository" },
   "expect" :  [
         { "headers" : { "Content-Type" : "application/json" } },
         { "status" : 201 },
         { "body" : { "name" : "GitHub", 
                      "description" : "Open Source repository",
                      "id" : "github",
                    }
        }
  ]
}

Another proposal is to use "response" as an alias for "assert" or "expect"

Again, this is for the dual-purpose of documenting a REST API call as well as validating a REST API call.
One can then transform this JSON document into more legible documentation as plain text, Markdown, HTML, etc:

POST http://www.example.com/myApi/myResource
Content-Type: application-json
Accept: application-json
{ "name" : "GitHub", "description" : "Open Source repository" },

Response status code: 201

Response headers:

Content-Type: application/json

Response body:

{ "name" : "GitHub", 
  "description" : "Open Source repository",
  "id" : "github",
}

The same UnRAVL script could also be used to generate curl

curl -XPOST \
     -HContent-Type:application-json \
     -HAccept:application-json \
     http://www.example.com/myApi/myResource

and and other client languges.

Allow "json" assertion to compare JSON "from" a variable

Enhance the default "json" assertion

   "assert" : { "json" : json-array-or-object }

to compare a JSON object or array that is stored in a variable:

   "assert" : { "json" : json-array-or-object, "from" : "varName" }

Although this can be done by binding both to variables and using a "groovy" assertion "var1 == var1",
the enhancement request #21 Extend "json" assertion to allow subset match; ignore order will not be easy to use from Groovy. So here would be the best place to add both features.

Switch to Spring RestTemplate for making API calls

Instead of org.apache.http, switch to using RestTemplate for making API calls.
This will allow clients which embed UnRAVL to supply their own RestTemplate
and therefore customize how REST calls are made.

Update .netrc parsing to allow spaces in passwords, port

Allow password with spaces in the .netrc file :

machine www.sas.com login testuser password 'my password contains spaces"

Allow port field in .netrc to allow matching host and port for REST API calls.

Allow using "user" as an alias for "login" in the .netrc file

See also authinfo. That is a C library and GPL so not suitable for inclusion in UnRAVL, but the specification is useful.

add "unwrap" : true to "links" extractor

Similar to the "json" extractor, add "unwrap" : true to allow converting the bound Jackson ObjectNode values to java.util.Map objects . This allows more concise Groovy assertions on the link values, without having to use textValue() on the values. For example

   "links" : [ "self", "createProvider" ],
   "assert" : [
    "createProvider.method.textValue() == 'POST'",
    "createProvider.rel.textValue() == 'createProvider'",
    "createProvider.uri.textValue() == '/providers'",
    "createProvider.type.textValue() == 'application/vnd.sas.datasources.provider+json'",
   ]

would be simpler/cleaner:

   "bind" : { "links" : "createProvider", "unwrap" : true },
   "assert" : [
    "createProvider.method == 'POST'",
    "createProvider.rel == 'createProvider'",
    "createProvider.uri == '/providers'",
    "createProvider.type == 'application/json'",
   ]

Another option is to add a "links" assertion which compares
links to expected JSON representations; see Issue #42

Decouple from JUnit

Reduce or remove coupling to JUnit, or make it optional.
Currently used in JUnitAssertion, EqualAssertion (deprecated, probably removing before releasing 1.0.0), TextBodyAssertion, and GroovyAssertion.

Add url encoding to "text" body generator

Allow passing a JSON object to the "text" generator and encode as application/x-www-form-urlencoded

{
   "POST" : "http://www.example.com/target",
   "body" : { "text" : {
                         "a" : "value of parameter a",
                         "b" : "value of parameter b"
                       }
            }
}

This would set the request header Content-Type to application/x-www-form-urlencoded
if not already set by "headers", and set the request body to the values, url encoded:

a=value%20of%20parameter%20a&b=value%20of%20parameter%20b

Add command-line option to generate JUnit reports

Currently, if you would like to run an UnRAVL script and generate an jUnit report, you need to call UnRAVL from Java.

It would be helpful if you could, instead, call the main UnRAVL driver (e.g. /src/main/bin/unravl.sh) and include a flag requesting an JUnit report:

export UNRAVL_OPT="-junit ./report.xml"
$ unravl script.json

If you were running this script inside a Jenkins job, you could then use an junit plugin to capture the results.

See #33

Seeking votes on how important this feature is.

Add variable substitution for all JSON types

unravl currently only substitution of string values

{ "name": "{var}" }

with a passed in number value of 5 would result in

{"name":"5"}

Rather than {"name":5} the actual JSON number value

We would like to support all the JSON types : array, null, number, boolean for substitution

I spoke with @DavidBiesack about this and we talked about doing substitution based possibly on a namespace convention. It ain't exactly pretty and is a little verbose but is explicit and wouldn't involve data collisions with existing JSON.

{"name": { "unravl:number": "var" } }
// Where var is 5 the resulting JSON object would be
{"name": 5}

There may be a better less verbose syntax, but this would certainly not involve collisions. Another proposal could be.

Security scanner flags version of log4j used

Running a security scanner over the UnRAVL jar results in a finding of a level HIGH security vulnerability for the version of log4j that UnRAVL uses -- version 1.2.17.

The finding is CVE-2017-5645. Information about that finding can be found here: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5645

From my examination of the sources, the finding appears to be mitigated by the fact that UnRAVL uses neither log4j's TcpSocketServer or UdpSocketServer. However, it is worth considering upgrading the log4j that is used to version 2.8.2 or later.

Thanks,
Ben

Oauth authentication does not honor in-script credentials

Using oauth authentication with valid values of clientid, clientsecret, user and password results in error:
No auth credentials for host
Supplying the same credentials in a .netrc file works.
Unlike older versions, supplying the credentials in .netrc file causes unravl to ignore the in script values.

logging options when running through JUnitWrapper

Is there a way to change the logging settings for unravl tests run through JUnit? One thing I noticed is that when a groovy assert fails, the log has something like this:

2015-12-22 14:36:14,441 Script UnRAVL:[now the transformations list should be empty again GET {HOST}/transformation/transformations], returned false

where the variables in the URI aren't expanded, and the error says "returned false" but doesn't say which assertion failed. In contrast, when a http status assert fails, the log message is more descriptive. ("Actual HTTP status code 200 did not match the expected status, 404 while running UnRAVL script" followed by the name of the test.)

One possibility is something like exceptions in Spock, where the assert that failed is included in the exception message. Or, is there a way to specify logging options for tests called through JUnitWrapper? I found the doc for logging options at https://github.com/sassoftware/unravl/blob/master/doc/Reference.md#logging, but don't know how to pass those into the JUnit calls.

thanks!

Update Guava dependency

com.sas:sas.unravl:1.2.2 has a dependency on Guava 18.0 which was released in
August 2014. Newer version exists, 20.0 was released on October of 2016.

Perform substitution in names for body and JSON objects in "env"

Per our email you replied:
UnRAVL only performs substitution in values, not in names, when processing embedded JSON (either for the body or for JSON objects in "env". I did not anticipate any use cases where the names of JSON values would require variable substitution.

In my test case I'm using IntelliJ which calls a Junit test that calls the JSON
I define
"env" : {

"str250":"B12345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789",
},

Then I try to pass in str250 to a map object in the json body "body" :
{
"json" : {
"properties":{"{str250}":"value1"}
}
},
But the key gets set to the literal {str250}. If I hardcode the string in key of the Map it works fine. Interestingly if I pass str250 to the value in the map it works.

Pretty print JSON output

It would be a lot easier to read the output if the JSON was indented. This could be done pretty easily by adding this section in the ApiCall class:

                if(isJson(headers))
                {
                    ObjectMapper mapper = new ObjectMapper();
                    mapper.enable(SerializationFeature.INDENT_OUTPUT);
                    Object json = mapper.readValue(bytes.toString(), Object.class);
                    String indented = mapper.writeValueAsString(json);
                    System.out.println(indented);
                }
                else
                    // TODO: pretty print XML
                    bytes.writeTo(System.out);

And this utility method:

private boolean isJson(Header[] headers)
{
    for(Header header : headers)
    {
        if(header.getName().equals("Content-Type") &&
           header.getValue().contains("json"))
        {
            return true;
        }
    }
    return false;
}

variables not expanded in @path strings

When referencing a "@location" to read a file from a URL/file, local variables are not expanded. thus, you can't do

{
  "env" : { "path" : "tst/src/scripts/" },
  ...
  "assert": [
    { "json" : "@{path}expected.json"}
    ]
}    

Add ability to cancel execution

Add UnRAVL.cancel() and UnRAVLRuntime.cancel() to support asynchronous execution by a client (such as a web service) and asynchronous canceling of the scripts(s).

Add decorators / filters

Add a "decorators" element (or maybe "filter") which acts like REST API filters.

Decorators can modify the request headers, URL, body and the response headers and body and http status code.

Authentication such as CAS Authentication and Basic Authentication are examples of decorators. For example, "basic" auth adds an "Authorization" header to the request.

Other decorators might "normalize" a response, for example, apply consistent sorting to an array in a response or in the environment, so that testing can be immune to trivial order differences, or filter/replace date/time values so tests are no sensitive to date/time changes.

Other decorators might normalize resource ids and allow for structural comparison of JSON to ignore differences between different runs of an API. For example, we such normalization might change a runtime resource id (from a URL) to a normalized references such as "projectId-1" or "projectId-2".

Add jsonpath assertion

I'd like to see a more straightforward assert/extractor using json path expressions:

"assert": [
    {"status": 200},
    {"jsonpath" : "$.links[0].rel == userPreferences"},
    {"jsonpath" : "$.links[0].method == GET"},
    {"jsonpath" : "$.links[0].type == application/vnd.sas.collection"},
    {"jsonpath" : "$.links[0].uri == /preferences/preferences/stpweb1"},
    {"jsonpath" : "$.links[1].rel == createPreferences"},
    {"jsonpath" : "$.links[1].method == POST"},
    {"jsonpath" : "$.links[1].type == application/vnd.sas.collection"},
    {"jsonpath" : "$.links[1].uri == /preferences/preferences/stpweb1"}
]

This uses the library 'com.jayway.jsonpath:json-path:2.+'

Add summary after JUnitWrapper.runScripts

Add a println to log the number of scripts that were run. This is very useful if it finds none, as that will tell the user that the directory or file pattern is wrong

Extend "json" assertion to allow subset match; ignore order

This enhancement would extend the "json" assertion that compares a JSON response to a benchmark JSON object. It would add a '"contains":true option to allow the expected value to be a subset of the actual JSON.

This operation would by default ignore order in arrays as well. An "assertOrder" : true option would override that and require array items in the JSON to match the order in the benchmark while still allowing a subset.

Finally, an option would allow naming an environment variable that the source JSON comes from, such as a value defined in a "groovy" extractor.

For example, if the JSON response was

{ "a" : "a string",
  "b" : { "x" : 1, "y" : true }
  "c" : [1,2,3, "another string"]
}

the existing "json" assertion only matches exactly:

"assert" : { "json" : { "b" : { "x : 1 }, "c" : [ 1,"another string" 2" ] } }

would fail.

With this enhancement, the following would pass:

"bind" : { "groovy" : { "b" : "jsonResponse.b.objectValue()" } },
"assert" : [ 
    { "json" : { "b" : { "x" : 1 }, "c" : [ 1,"another string", 2 ] },   "contains" : true },
    { "json" : { "b" : { "y" : true }, "c" : [  ] },                     "contains" : true },
    { "json" : { "c" : [ 1,"another string" ] },                         "contains" : true, "assertOrder" : true },

    { "json" : { "x" : 1, "y" : true },                                  "from" : "b"},
    { "json" : { "x" : 1 },                                              "contains" : true, "from" : "b" }
]

Add option to disable env var expansion in "text" and "json" body generators

Add an "expand" : false option for the"text" and "json" body generators.

{
   "POST" : "http://www.example.com/target",
   "body" : { "text" : "Some text that should not have {env} expansion",
                   "expand" : false
                 }
}

and

{
   "POST" : "http://www.example.com/target",
   "body" : { "json" : 
                      { "stringData" : "Some text that should not have {env} expansion",
                         "numericData" : 3.14159
                      },
                   "expand" : false
                 }
}

The default value would be false.

Add iteration

Support iteration operations. This could be tail recursion on a list in the environment, or a foreach operation a JSONPath or XMLPath result that returns a collection (such as accessing the links of an object and iterating through the pages of a collection)

Support multi-part form submission

Some APIs support POSTing form data, multipart/form-data. research this, including how often this is actually
done in REST APIs, and design a "body" format for specifying form data.

For example:

{ "body" : 
    { "multiPartForm" : [ 
        {  "text" : [ "array", "of", "text", "lines" ], 
           "name" : "errors.log", 
           "Content-Type" : "text/plain" },
     {  "text" : "@src/test/data/screenshot.png, 
           "name" : "screenshot.png", 
           "Content-Type" : "image/png" }, 
        { ... } 
        ] ,
    "name" : "form-name"
    }
}

This would basically be an array of existing "body" elements ("text", "binary"), but adding a name and Content-Type etc. to each part.

Allow encoded body of requests

We should have a way to encode the "body" of a submission in some way that does not require us to escape other media types within the body of a UNRAVL submission. Example: SAS Code within the string needs to be extra careful of escaping " or ' values or the JSON of UNRAVL is invalid?

I did not see this covered in https://github.com/sassoftware/unravl/blob/master/doc/Body.md. It does mention BINARY, but i think this is more ability to specify encoding "BASE64" for example and body value, and have it "unwrapped" before submission.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.