3 Pollen-rock Server Specification
Pollen-rock server provides a set of RESTful APIs for the front end to query project information.
Note: these APIs and this doc are still under construction. They are subject to changes at this point.
3.1 Query the Server
All API resource starts with /rest/. Let’s take the following project structure as an working example.
/tmp/project/ |
|- pollen.rkt |
|- file1.html.pm |
|- file2.html.pm |
|- dir1/ |
|- file3.html.pm |
|- dir2/ |
All JSON output in this section are additionally rendered by pretty print. The command output is generated by passing the JSON into python -m json.tool, as in curl http://localhost:8000/rest/fs/ | python -m json.tool
file1.html.pm and file2.html.pm are two pollen source files. pollen.rkt has the following contents
#lang racket |
|
(provide (all-defined-out)) |
|
(define x 1) |
|
(define (tag0 x . y) |
`(mytag ,x ,@y)) |
Now open a terminal, and start pollen-rock
$ raco pollen-rock |
In another terminal, we can start querying the server. Let’s list the project root directory
$ curl http://localhost:8000/rest/fs |
{ |
"errno": 0, |
"items": [ |
"dir1/", |
"dir2/", |
"file1.html.pm", |
"file2.html.pm", |
"pollen.rkt" |
], |
"mtime": 1547790867 |
} |
What about the dir1 directory
$ curl http://localhost:8000/rest/fs/dir1 |
{ |
"errno": 0, |
"items": [ |
"file3.html.pm" |
], |
"mtime": 1547790866 |
} |
What about listing some directory called non-exists?
$ curl http://localhost:8000/rest/fs/non-exists |
{ |
"errno": 1 |
} |
Let’s read the contents of file3.html.pm
$ curl http://localhost:8000/rest/fs/dir1/file3.html.pm |
{ |
"contents": "#lang pollen\n\nfile3 contents\n\n", |
"errno": 0, |
"mtime": 1547791032 |
} |
Let’s get all tags visible in file3.html.pm.
$ curl http://localhost:8000/rest/tags/dir1/file3.html.pm |
{ |
"errno": 0, |
"tags": [ |
{ |
"arity-at-least": true, |
"kind": "procedure", |
"arity": 1, |
"required-keywords": [ |
|
], |
"name": "tag0", |
"all-keywords": [ |
|
] |
}, |
{ |
"kind": "variable", |
"name": "x", |
"type": "number", |
"value": 1 |
} |
] |
} |
You can tell Pollen-rock can do quite a lot here. Let’s dive into the API specification in next section.
3.2 RESTful API
Pollen-rock supports requests that are form-url-encoded, i.e. requests whose Content-Type is application/x-www-form-urlencoded.
For each API, we first list its designated url (the resource), and then the query parameter, the request parameter, and the response parameter. It’s necessary to make it clear what and where these parameters are in the request and response:
- query parameter (GET HTTP request only): It’s the {6} and {7} of the following diagram (borrowed from URL Structure)
http://sky@www:801/cgi-bin/finger;xyz?name=shriram;host=nw#top
{6} {----7-------------}
request parameter (POST HTTP request only): request parameter is in the payload of an HTTP POST request. Pollen-rock currently supports only application/x-www-form-urlencoded.
response parameter: Response from the server. Pollen-rock now returns only JSON. So all the parameters are keys (properties) of JSON object.
3.2.1 POST /rest/fs/$path
This API is for file system operations.
Query parameter: None
Request parameter:
- op: string. It can be one of
"mv": rename $path into the string given in data
"mkdir": create new directory $path
"rm": remove $path
"write": write data into file $path
data: string (optional). extra data
mtime: integer (optional). the server always writes the given data if mtime is 0 or not provided. The server rejects the request if the on-disk mtime does not match the given one.
errno: int. 0 means no error. Negative number means Pollen-rock internal error. Positive errno matches the Linux errno
message: string. Extra message from the server. Usually this contains error messages if errno is not 0
Examples: create directory dir3, and move dir3 to dir4.
$ curl -X POST -d "op=mkdir" http://localhost:8000/rest/fs/dir3 |
{ |
"errno": 0, |
"message": "" |
} |
$ curl http://localhost:8000/rest/fs/ |
{ |
"errno": 0, |
"items": [ |
"dir1/", |
"dir2/", |
"dir3/", |
"file1.html.pm", |
"file2.html.pm", |
"pollen.rkt" |
], |
"mtime": 1547791126 |
} |
$ curl -X POST -d "op=mv&data=dir4" http://localhost:8000/rest/fs/dir3 |
{ |
"errno": 0, |
"message": "" |
} |
3.2.2 GET /rest/fs/$path
This API is for list directory or reading files.
Query parameter: None
errno: int. 0 means success. non-zero means the operation has failed
items: string array. If $path is a directory, items contains the directory contents. All subdirectory names have / suffix.
contents: string. If $path is a regular text file, contents is the contents of that file.
mtime: integer. The last modification seconds of this file.
Examples: get the contents of file3.html.pm
$ curl http://localhost:8000/rest/fs/dir1/file3.html.pm |
{ |
"contents": "#lang pollen\n\nfile3 contents\n", |
"errno": 0, |
"mtime": 1547791032 |
} |
{ |
"errno": 0, |
"items": [ |
"dir1/", |
"dir2/", |
"dir4/", |
"file1.html.pm", |
"file2.html.pm", |
"pollen.rkt" |
], |
"mtime": 1547791190 |
} |
3.2.3 GET /rest/tags/$file
Fetch defined tags of a racket module $file. Note that $file must be a racket module.
TODO: It would be useful to accept a query parameter to return a specific tag
errno: int. 0 means success. 1 means that error has occurred.
- tags: objects array. array of json objects containing procedure or variable information.
name: string. Tag name
kind: string. Either "variable" or "procedure".
type: string or null. (Variable only) Valid values are "boolean", "number", "string", "char", "symbol", null. Also see value.
value: any. (Variable only) The value of the tag. The type of the value is indicated by the type property.
arity: number. (Procedure only) This is the arity of the procedure. If arity-at-least is true, this value is the minimum arity that this procedure requires.
arity-at-least: boolean. (Procedure only) See arity.
all-keywords: string array or false. (Procedure only) All keywords of a procedure, including optional and required keywords. If this is false, it can accept any keywords.
required-keywords: string array. (Procedure only) Required keywords.
$ curl http://localhost:8000/rest/tags/file1.html.pm |
{ |
"errno": 0, |
"tags": [ |
{ |
"all-keywords": [], |
"arity": 1, |
"arity-at-least": true, |
"kind": "procedure", |
"name": "tag0", |
"required-keywords": [] |
}, |
{ |
"kind": "variable", |
"name": "x", |
"type": "number", |
"value": 1 |
} |
] |
} |
3.2.4 GET /rest/config/$file
Get project configuration of the given $file. If pollen.rkt doesn’t exist, this API fetches pre-defined tags from Setup.
It would be useful to accept a query parameter to return a specific config
Response parameter: same as GET /rest/tags/$file. However, this API returns only variables of the setup module.
3.2.5 GET /rest/watch/$file
Do HTTP long polling on the given $file. The HTTP request returns only when the modified time of $file has changed.
mtime: int (optional). Return immediately if the last modified time of the file is greater than this mtime. This is parameter is not provided, the return occurs only when the modified time of the file has changed.
errno: int. 0 means file changed. 1 means no such file.
mtime: int. Last modified time when errno is 0. When errno is 1, mtime can be anything
Example: the following command would block until touch file1.html.pm runs.
$ (sleep 10 && touch file1.html.pm) & |
|
$ time curl http://localhost:8000/rest/watch/file1.html.pm |
{"mtime":1514347321,"errno":0} |
|
real 0m9.445s |
user 0m0.012s |
sys 0m0.021s |
3.2.6 GET /rest/search/$file
Search source and output file.
If the given file is a pollen source file, i.e. pp, pm, p, etc., Pollen-rock always returns source and output paths, and source-exists indicates whether the source file exists. If the given file is not a pollen source, it’s treated as an output file, and returns non-zero errno if no source files on the file system can generate the output, and returns 0 errno and set source and output accordingly, in which case, source-exists is always true.
Query parameter: None
errno: int. 0 means no error, non-zero means some error has occurred
source-exists: bool. Whether the source exists
source: string. The source path relative to project root. The value is undefined when errno is non-zero.
output: string. The output path relative to project root. The value is undefined when errno is non-zero.
Example: the following command gets the output path of one nonexistent pollen source
$ curl http://localhost:8000/rest/search/nonexist.html.pm |
{ |
"errno": 0, |
"output": "nonexist.html", |
"source": "nonexist.html.pm", |
"source-exists": false |
} |
The following command demonstrates querying an output path that doesn’t exist.
$ curl localhost:8000/rest/search/nonexist-dir/ |
{ |
"errno": 1, |
"output": "", |
"source": "", |
"source-exists": false |
} |
3.2.7 GET /rest/render/$file
Render the given pollen source $file
Query parameter: None
errno: int. 0 means no error, 1 means no such file, 2 means render failed.
location: string. Rendered file name. The location will be always present even if render fails.
Example: render file3.html.pm.
$ curl http://localhost:8000/rest/render/dir1/file3.html.pm |
{ |
"errno": 0, |
"location": "dir1/file3.html" |
} |