API
WebSocket
REST gives you the final output. A WebSocket connection gives you output as it appears, and lets your user answer a program while it runs.
Use it for a terminal, a program that prompts the user, or anything where waiting until the end is not good enough.
Everything about languages, versions and program parameters is the same as REST. What changes is how you connect and how messages arrive.
How the connection is made
Your server holds the secret. The browser holds only a token, and talks to us directly.
Your server is only involved in getting the token. After that the conversation is between your user and us, which is what makes an interactive program feel immediate.
Get a token
The browser connects to us directly, so your client secret must not be involved. Your server exchanges the secret for a short-lived token first.
curl -X POST 'https://api.jdoodle.com/v1/auth-token' \
-H 'Content-Type: application/json' \
-d '{
"clientId": "your_client_id",
"clientSecret": "your_client_secret"
}'// Java 11 or newer. Runs on your server, never in a browser.
String body = "{"
+ "\"clientId\": \"your_client_id\","
+ "\"clientSecret\": \"your_client_secret\""
+ "}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.jdoodle.com/v1/auth-token"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());// Node 18 or newer. Runs on your server, never in a browser.
const response = await fetch('https://api.jdoodle.com/v1/auth-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clientId: 'your_client_id',
clientSecret: 'your_client_secret'
})
})
const { token } = await response.json()
// Send this token to the browser. Never the secret.# Runs on your server, never in a browser.
import requests
response = requests.post(
"https://api.jdoodle.com/v1/auth-token",
json={
"clientId": "your_client_id",
"clientSecret": "your_client_secret",
},
)
token = response.json()["token"]{ "token": "your_generated_token" }The token lasts three minutes, and you can run as many programs as you like in that time. Getting one costs one credit, on top of the credit each run costs, so one token covering a whole session is cheaper than one per run. See credits and pricing.
Request a token when a user is about to run something, rather than fetching one and keeping it.
Connect
https://api.jdoodle.com/v1/stompThe connection speaks STOMP over SockJS, so use a SockJS client with a STOMP wrapper rather than a raw WebSocket.
The examples below are JavaScript because this half runs in your user's browser. Your server's part is getting the token above, which you can do in any language.
| What | Where |
|---|---|
| Subscribe to | /user/queue/execute-i |
| Send messages to | /app/execute-ws-api-token |
// sockjs-client and webstomp-client, loaded in the browser
const client = webstomp.over(new SockJS('https://api.jdoodle.com/v1/stomp'))
client.connect({}, () => {
client.subscribe('/user/queue/execute-i', (message) => {
const status = Number(message.headers.statusCode)
if (status === 201) console.log('started')
else if (status === 204) console.log('finished')
else console.log(message.body)
})
client.send(
'/app/execute-ws-api-token',
JSON.stringify({
script: 'print("Hello, World!")',
language: 'python3',
versionIndex: '0'
}),
{ message_type: 'execute', token }
)
})Every message carries two headers:
token. The token your server obtained.message_type. Eitherexecuteto start a program, orinputto answer one that is running.
Start a program
Send a message_type of execute, with the same fields REST takes:
{
"script": "name = input()\nprint(f\"Hello, {name}\")",
"language": "python3",
"versionIndex": "0"
}Answer a running program
Send a message_type of input with what your user typed. The body is the
text itself rather than JSON, and a newline is \n.
client.send('/app/execute-ws-api-token', userTyped + '\n', {
message_type: 'input',
token
})This is the part REST cannot do. You do not need to know the input before the program starts.
What comes back
Output arrives as messages on the queue you subscribed to. The status on each message says what it is:
| Status | Meaning |
|---|---|
| 201 | Execution started |
| 204 | Execution time |
| 206 | Output files |
| 400, 401 | Authentication problem |
| 429 | Daily limit reached |
| 410, 500 | Server error |
A working sample
A complete HTML page that connects, runs a program, and lets you answer it while it runs. Save it, open it in a browser, paste a token, and press Run.
Download jdoodle-websocket.html
It is one file with no build step. The two libraries load from a CDN, and the whole flow is about eighty lines, so it is easier to read than to describe.
When REST is the better choice
REST is less to build and less to get wrong. Choose the socket only when your users need to interact with a running program, or when output arrives over time and they should see it as it happens.
What next
Whichever interface you use, the language and version values are the same.