API

ASP.NET Maker supports API that enables you to perform CRUD (Create, Read, Update and Delete) for the tables in the generated web application. You can issue the request to the API (e.g. via JavaScript codes), get the response as JSON (Javascript Object Notation), interpret and present the result as you like it. The default address for the API request is the api subfolder of the generated application (i.e. <mysite>/api).

 

Understanding the API

The API is implemented on the basis of the list, view, add, edit and delete pages supported for each table selected for generation. The basic supported API actions are add (Create), list / view (Read), edit (Update), delete (Delete), login (Authenticate User, if Security is enabled) and file (Get file content).

The standard exchange of information with the API is shown in the following examples (using the "cars" table of the demo database for demonstration):

Example 1 - Get a record by key (view action)

- Javascript (Assuming "input-id" is an input for key value)
$("#input-id").change(function() {
    var url = "api/", object = "<Table>", action = "view", key = encodeURIComponent($(this).val());
    $.get(url + action + "/" + object + "/" + key, function(res) {
// Get response from View page API
        if (res && res.success) {
            var row = res[object];
            alert(JSON.stringify(row));
// Show output JSON
        } else {
            alert(res.failureMessage);
        }
    });
});


- HTTP Request
 GET /api/view/cars/1
 Accept: application/json


- HTTP Response
 200 OK
 {
     "success": true,
     "version": "15.0.0",
     "cars": {
         "ID": 1,
         "Trademark": 1,
         ...
     }
 }


Example 2 - Create a record (add action)

- Javascript (Assuming "btn-id" is the submit button for the add form)
$("#btn-id").click(function() {
    var url = "api/", object = "<Table>", action = "add", data = $(this.form).serialize();
    data += "&" + ew.TOKEN_NAME + "=" + ew.ANTIFORGERY_TOKEN;
    
$.post(url + action + "/" + object, data, function(res) { // Get response from Add page API
        if (res && res.success) {
            var row = res[object];
            alert(JSON.stringify(row));
// Show output JSON
        } else {
            alert(res.failureMessage);
        }
    });
});


Your data should be in JSON

- HTTP Request

 POST /api/add/cars
 { "Trademark": "1", "Model": "2", "HP": 3, ... }
 Content-Type: application/json
 Accept: application/json

Notes

  1. If your data is JSON, make sure you have set the content type to application/json and make sure you use FULL JSON syntax


- HTTP Response (success)
 200 OK
 {
     "success": true,
     "version": "16.0.0",
     "cars": {
         "ID": 16,
         "Trademark": 1,
         ...
     }
 }


- HTTP Response (failure)
 200 OK
 {
     "success": false,
     "version": "16.0.0",
     "failureMessage": "<failed reason>"
 }


The following actions are supported. For list/view/file actions, the request is expected as HTTP GET, for other actions the request is expected as HTTP POST.

Action Parameters Request Response
list (Get list of records) action=list
object=<Table>
start=<StartRecordNumber> (Optional, start record number, default = 1)
recperpage=<RecordsPerPage> (Optional, record per page, default = [Records per page] setting, requires activating the [Selectable page sizes] setting)
order=<Field> (Optional, sort by the specified field, requires activating the [Sort] setting in list page)
ordertype=ASC|DESC (Optional, sort ascending (ASC) or descending (DESC), requires activating the [Sort] setting in list page)
<Field>=<FieldValue> (Optional, search field by value, requires activating the [Advanced/Extended Search] setting in list page)
GET /api/list/cars Successful response
{ "success": true,"version": "16.0.0",
 "cars": [ { "ID": 1, "Trademark": 1, ... },
        { "ID": 2, "Trademark": 1, ... } ] }

Failed response
{ "success": false,"version": "16.0.0",
 "failureMessage": "<failed reason>" }

view (Get single record by key) action=view
object=<Table>
<KeyField>=<KeyFieldValue> (key field value)
GET /api/view/cars/1 Successful response
{ "success": true, "version": "16.0.0",
 "cars": { "ID": 1, "Trademark": 1, ... } }

Failed response
See failed response for list

add (Insert a new record) action=add
object=<Table>
<Field>=<FieldValue> (field to be inserted)
POST /api/add/cars
 Trademark=1&...
Successful response
{ "success": true, "version": "16.0.0",
 "cars": { "ID": 16, "Trademark": 1, ... } }

Failed response
See failed response for list

edit (Update an existing record by key) action=edit
object=<Table>
<KeyField>=<KeyFieldValue> (key field value)
<Field>=<FieldValue> (field to be updated)
POST /api/edit/cars/1
Trademark=2&...
Successful response
{ "success": true, "version": "16.0.0",
 "cars": { "Trademark": 2, ... } }

Failed response
See failed response for list

delete (Delete an existing record by key) action=delete
object=<Table>
<KeyField>=<KeyFieldValue> (key field value)
POST /api/delete/cars/1
Successful response
{ "success": true, "version": "16.0.0",
 "cars": { "ID": 1, "Trademark": 1, ... } }

Failed response
See failed response for list

login (Authenticate an user, see Authenticate user with JWT) action=login
username=<UserName> (user name value)
password=<Password> (password value)
POST /api/login
username=admin&password=master
Successful response
{ "JWT": "<JsonWebToken>" }

Failed response
401 Unauthorized
file (Get file content) action=file
object=<Table>
field=<Field>
<KeyField>=<KeyFieldValue> (key field value)
GET /api/file/cars/Picture/1 Successful response
For blob field (e.g. Picture field in cars table), binary content of file field with the correct content type
For string field (e.g. Photo field in employees table), JSON response of file locations:
{ "Photo": { "EmpID1.jpg": "http://<my-site>/upload/EmpID1.jpg" }, "version": "16.0.0" }

Failed response
Empty response

 

Authenticate User with JWT (JSON Web Token)

API is stateless. Each API request is independent of each other and no session data is stored in the server to record the current state of the API requests. To access protected resources from the API, you need to authenticate the user first by getting a JSON Web Token (JWT) using the login action, then pass the JWT as an authentication header in subsequent API requests. Note that each JWT has a limited timespan, so you may need to re-authenticate the user again once the token has expired.

You can customize the following JWT parameters via Tools -> Advanced Settings.

Settings Description Value
API JWT signing secret key The secret key used to sign the JWT. Non-optional, make sure you use different values for different projects and keep it in a secret place
API JWT signing algorithm The algorithm used to sign the JWT. Default is HmacSha256. For more possible values refer to JWT web site below.
https://github.com/dvsekhvalnov/jose-jwt#aspnet-core-mvc-jwt-authentication
API access time after login (seconds) Time you can access the protected resources after login Default is 10. If you want immediate access, you can change it to 0.
API expire time after login (seconds) The JWT expiry time Default is 600 (10 minutes). You will need to authenticate again once the JWT expires.
API Issuer The issuer is a claim and indicates which application generated this token in the first place. Default is localhost. You will need to enter your domain
API Audience The Audience is a claim and indicates which application might interact with your API Default is "*". You will need to enter the domain of your client's application
API Access-Control-Allow-Origin header Set the Access-Control-Allow-Origin header for Cross Region Resource Sharing (CORS) access. If not set, only allow access to the API from the same domain. Default is Empty. You will need to enter the domain of your client's application

To understand more about JWT, please visit:
https://jwt.io/introduction/

The following Javascript shows how to get a protected resource from the API by JWT. Authenticate the user first by clicking the login button. Then click the Get order record button to get the order record which is a protected resource.
$(function() {
    var store = store || {};
    
/*
     * Store JWT
     */

    store.setJWT = function(data) {
        this.JWT = data;
    }
    
/*
     * Login
     */

    $("#frm-login").submit(function(e) {
        e.preventDefault();
        var data = $("#frm-login").serialize();
        data += '&action=login';
        $.post("api/login", data, function(data) {
            $("button").removeAttr("disabled");
            store.setJWT(data.JWT);
        }).fail(function(xhr, status, error) {
            alert("login failed. status: " + status + ", error: " + error);
        });
    });
    
/*
     * Get protected resource
     */

    var getProtectedResource = function(e) {
        e.preventDefault();
        $.ajax({
            url: "api/view/orders/10248",
            type: "GET",
            success: function(data, status, xhr) {
                var out = (data && typeof data === 'object') ? JSON.stringify(data) : data;
                alert(out);
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert("status: " + xhr.status + ", error: " + thrownError);
            },
            beforeSend: function(request) {
// Set JWT header
                request.setRequestHeader('Authorization', 'Bearer ' + store.JWT);
            }
        });
    }
    $("#btn-with-token").click(getProtectedResource);
});

<form id="frm-login" method="post">
User name: <input type="text" name="username" value="admin">
Password: <input type="text" name="password" value="master">
<input type="submit" value="Login">
</form>
<button id="btn-with-token" type="button" disabled>Get order record</button>

 

Create Your Own API Action

Beside the built-in API actions, you can add new API actions by writing your custom API handler and put the codes in server side ApiController_Action (see Server Events and Client Scripts).

Example 1 - Hello world
public class HelloController : ApiController
{
    [HttpGet("{user}")]
    public IActionResult Get([FromRoute] string user)
    {
        return Content("Hello " + user); // Get the value from route
    }
}

The user can now access the URL /api/hello/John to get the response text "Hello John".

 

Example 2 - Get product by product name
public class GetProductByNameController : ApiController
{
    [HttpGet("{name}")]
    public IActionResult Get([FromRoute] string name)
    {
        var rs = ExecuteRow("SELECT * FROM products WHERE ProductName = '" + AdjustSql(name) + "'");
        return Json(rs); // Get the value from route
    }
}

The product data can now be accessed using the following JavaScript:

$.get("api/GetProductByName/Chai", function(res) {
// Get response from API
    console.log(res);
// Show the result in console
});

 

 ©2004-2019 e.World Technology Ltd. All rights reserved.