Skip to content

Commit

Permalink
Enhanced RESTful API example
Browse files Browse the repository at this point in the history
  • Loading branch information
cpq committed Oct 15, 2014
1 parent a6598a1 commit 790daab
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 50 deletions.
66 changes: 66 additions & 0 deletions examples/restful_api/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>RESTful API demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
* { outline: none; font: 16px/1.4 Helvetica, Arial, sans-serif; }
body {
background-color: #cde; margin: 0;
padding: 0; font: 16px/1.4 Helvetica, Arial, sans-serif;
}
div.content {
width: 800px; margin: 2em auto; padding: 20px 50px;
background-color: #fff; border-radius: 1em;
}
label { display: inline-block; min-width: 7em; }
input { border: 1px solid #ccc; padding: 0.2em; }
a:link, a:visited { color: #69c; text-decoration: none; }
@media (max-width: 700px) {
body { background-color: #fff; }
div.content { width: auto; margin: 0 auto; padding: 1em; }
}
</style>

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script language="javascript" type="text/javascript">
jQuery(function() {

$(document).on('keyup', '#n1, #n2', function() {
$.ajax({
url: '/api/sum',
method: 'POST',
dataType: 'json',
data: { n1: $('#n1').val(), n2: $('#n2').val() },
success: function(json) {
$('#result').html(json.result);
}
});
});

});
</script>
</head>
<body>
<div class="content">
<h1>RESTful API demo.</h1>

<p>
This page demonstrates how Mongoose web server could be used to implement
RESTful APIs. Enter numbers below, and press Submit. Browser will send
two numbers to <tt>/api/sum</tt> URI, Mongoose calclulates the sum of
two and returns the result.
</p>

<div>
<label>Number 1:</label> <input type="text" id="n1" />
</div><div>
<label>Number 2:</label> <input type="text" id="n2" />
</div><div>
<label>Result:</label> <span id="result">&nbsp;</span>
</div><div>

</div>
</body>
</html>
70 changes: 20 additions & 50 deletions examples/restful_api/restful_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,32 @@
#include <stdlib.h>
#include "mongoose.h"

static int static_value = 123; // Exposed and changeable via the form
static const char *s_no_cache_header =
"Cache-Control: max-age=0, post-check=0, "
"pre-check=0, no-store, no-cache, must-revalidate\r\n";

static void print_html_form(struct mg_connection *conn) {
mg_send_header(conn, "Content-Type", "text/html");
mg_send_header(conn, "Cache-Control", "max-age=0, post-check=0, "
"pre-check=0, no-store, no-cache, must-revalidate");
static void handle_restful_call(struct mg_connection *conn) {
char n1[100], n2[100];

// Note that all the following normally should reside in static HTML page
mg_printf_data(conn, "%s", "<html><head>");
// It is better to use local copy though
mg_printf_data(conn, "<script src=\"%s\"></script>",
"http://code.jquery.com/jquery-1.11.0.min.js");
mg_printf_data(conn, "%s", "<script> jQuery(function() {\n");
// Here is the ajax call that fetches data from the device and
// updates the form
mg_printf_data(conn, "%s", "$.ajax({ url: '/get_value', dataType: 'json', "
"success: function(d) { $('#val').val(d.value); }});\n");
// This ajax call is triggered when submit button is pressed. It sends new
// value to the device.
mg_printf_data(conn, "%s", "$(document).on('click', '#button', function() {"
" $.ajax({ url: '/set_value', dataType: 'json', "
" data: { new_value: $('#val').val() } });\n"
" return false; });\n");
mg_printf_data(conn, "%s", "});</script>");
mg_printf_data(conn, "%s", "</head><body>");
mg_printf_data(conn, "%s", "<h1>Ajax form submission example</h1>");
mg_printf_data(conn, "%s", "<form>");
mg_printf_data(conn, "%s", "Device value: <input type=text id=val />");
mg_printf_data(conn, "%s", "<input type=submit id=button />");
mg_printf_data(conn, "%s", "</form>");
mg_printf_data(conn, "%s", "</body></html>");
// Get form variables
mg_get_var(conn, "n1", n1, sizeof(n1));
mg_get_var(conn, "n2", n2, sizeof(n2));

mg_printf_data(conn, "{ \"result\": %lf }", strtod(n1, NULL) + strtod(n2, NULL));
}

static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
if (ev == MG_REQUEST) {
if (strcmp(conn->uri, "/get_value") == 0) {
mg_printf_data(conn, "{\"value\": %d}", static_value);
} else if (strcmp(conn->uri, "/set_value") == 0) {
// This Ajax endpoint sets the new value for the device variable
char buf[100] = "";
mg_get_var(conn, "new_value", buf, sizeof(buf)); // Get form variable
static_value = atoi(buf); // Set new value
mg_printf_data(conn, "%s", "{\"success\": true}");
printf("Setting value to [%d]\n", static_value); // Debug trace
} else {
// Better way is to set "document_root" option, put "index.html" file
// into document_root and return MG_FALSE here. We're printing HTML
// page by hands just to keep everything in one C file.
print_html_form(conn);
}
return MG_TRUE;
} else if (ev == MG_AUTH) {
return MG_TRUE;
switch (ev) {
case MG_AUTH: return MG_TRUE;
case MG_REQUEST:
if (!strcmp(conn->uri, "/api/sum")) {
handle_restful_call(conn);
return MG_TRUE;
}
mg_send_file(conn, "index.html", s_no_cache_header);
return MG_MORE;
default: return MG_FALSE;
}

return MG_FALSE;
}

int main(void) {
Expand Down

0 comments on commit 790daab

Please sign in to comment.