SuiteCRM 8 and current status of REST API?

I’m going to soon be working on a project that will mainly use Microsoft PowerApps as the front-end and SuiteCRM as the backend database.

Are there any big changes coming down the pike as far as the REST API? Or big changes, in general?

The new SuiteCRM 8 uses a GraphQL API.

People think that the v8 API is the API of SuiteCRM v8 but it’s not, it was there before.

There’s API v4 for SuiteCRM v7
There’s API v8 for SuiteCRM v7
There’s GraphQL API for SuiteCRM v8 (although the previous APIs still work with the legacy part).

I’m afraid there’s not much documentation on the GraphQL API, but I have a few posts here howing how to make custom calls for GraphQL. And the entire SuiteCRM v8 codebase if filled with examples of that API because the entire UI goes through the API.

Hi @pgr

Is there any doc or examples calling a graphql api for suitecrm8?

I’m developing a module, and set the record to be legacy view. I wanted to add a javascript to call the graphql api of suite8 by ajax call. It returns 403 (forbideen): Seems that I need to pass an extra arguments. Do u have any idea?

For example:

    var query = " \                                                                    
     getRecordList(module:'custom_Module', limit:20, \
         criteria:{ \                                                                  
             filters:{ \                                                               
                 inmutados:{ \                                                                                                                                                
                     field:'terminado', \                                              
                         operator:'=', \
                         values:['1'] \
                 } \
             } \            
         }) \              
     { \                          
         records \    
     }";                                                                               
                                                                                       
     var r = $.ajax({                                                                  
         async: true,
         type: 'POST',               
         url: '/api/graphql',                                                          
         data: {                                                                       
             'operationName': 'getRecordList',                                                                                                                                
             'query': query
         }                                                                             
     }).done(function() {                                                                                                                                                     
         console.log(r.responseText)
     });

Thanks!

Sorry, I don’t know.

Does it work if you are previously logged in, in that browser?

Maybe check one of the GraphQL requests that the UI does (in Network tab of browser developer tools) and try to replicate everything…

Hi! it seems that the issue is the missing header of xsrf token.

I did not found how to create it, to send it to the graphql api.

I think the general idea is to first send a Login request, and that should return the proper cookie; you need to store it and then send it the subsequent requests.

That’s the general idea… but I haven’t tried it.

Hi @pgr @RMN ! finally I could request to api graphql of suite8 from a custom javascript. I’m rendering the edit/detail page with legacy view.

  1. I need it to get XSRF-TOKEN to send it as a header to the ajax request.
  2. Create a request variable to get a list of records (query)
  3. Create a variables var to set the criteria and other stuff.
    var token = getCookie('XSRF-TOKEN');
    console.log('token');                 
    console.log(token);                                                                

    var operationName = 'getRecordList';

    var query = `
    query getRecordList($module: String!, $limit: Int, $offset: Int, $criteria: Iterable, $sort: Iterable) {
        getRecordList(module:$module, limit:$limit, offset: $offset, criteria: $criteria, sort: $sort) { 
            id 
            _id 
            meta 
            records 
            __typename 
        }
    }
    `;

    var variables = {
        'criteria': {
            'name': "",
            'orderBy': "",
            'searchModule': "gcoop_estados",
            'sortOrder': "", 
            'filters': {
                'terminal': { 
                    'field': "terminal", 
                    'fieldType': "bool",
                    'operator': "=", 
                    'values': [1] 
                } 
            }     
        }, 
        'module': 'gcoop_estados', 
        'limit': 20,  
        'offset': 0,   
        'sort': {       
            'orderBy': "",
            'sortOrder': "DESC"  
        }  
    };     
            
    var r = $.ajax({ 
        async: true,   
        url: '/api/graphql',
        method: 'POST',   
        ContentType: 'application/json',  
        headers: {                                   
            'Accept': 'application/json, text/plain, */*', 
            'Content-Type': 'application/json',              
            'X-XSRF-TOKEN': token                               
        }, 
        data: JSON.stringify({
            oerationName: operationName, //'getRecordList', 
            query: query,
            variables: variables 
        }) 
    }).done(function() { 
        console.log(r.responseText) 
        var response = $.parseJSON(r.responseText); 
        let records = response.data.getRecordList.records; 

        let dropdown = $('#status'); 
        dropdown.empty();                
        dropdown.prop('selectedIndex', 0);

        $.each(records, function(key, entry) {
            console.log(key);                             
            console.log(entry);                          
            console.log(entry.attributes.id); // key
            console.log(entry.attributes.name); // label
        })
    });

The response looks something like this:

{
	"data": {
		"getRecordList": {
			"id": "/api/record-list/gcoop_estados",
			"_id": "gcoop_estados",
			"meta": {
				"offsets": {
					"current": 0,
					"next": -1,
					"prev": -1,
					"end": 0,
					"total": 1,
					"totalCounted": false
				},
				"ordering": {
					"orderBy": "",
					"sortOrder": "ASC"
				}
			},
			"records": [
				{
					"id": "41f2fd13-2959-9d80-99c4-63492b14e2fe",
					"module": "gcoop-estados",
					"type": "gcoop_estado",
					"attributes": {
						"module_name": "gcoop_estados",
						"object_name": "gcoop_estado",
						"id": "41f2fd13-2959-9d80-99c4-63492b14e2fe",
						"name": "Finalizado",
						"date_entered": "2022-10-14 09:27:39",
						"date_modified": "2022-10-14 09:27:39",
						"modified_user_id": "1",
						"modified_by_name": {
							"user_name": "admin",
							"id": "1"
						},
						"created_by": "1",
						"created_by_name": {
							"user_name": "admin",
							"id": "1"
						},
						"description": "",
						"deleted": "",
						"codigo": "004",
						"terminal": "true",
						"gcoop_sector_id": "",
						"gcoop_sector_name": {
							"name": "",
							"id": ""
						}
					},
					"acls": [
						"list",
						"edit",
						"view",
						"delete",
						"export",
						"import"
					]
				}
			],
			"__typename": "RecordList"
		}
	}
}

Hope it helps!

2 Likes

Thanks @lukio , this will be very useful :ok_hand:

Hello @lukio
could you post the code to the getCookie function or point me to a documentation about how it needs to look like in order to obtain the cookie?

function getCookie(cname) {
    let name = cname + "=";
    let ca = document.cookie.split(';');
    for(let i = 0; i < ca.length; i++) {
        let c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

Thank you very much.
It’s not the bit I’ve been hoping for.

What’s the endpoint URL to login and retrieve the token / cookie?

Hi @Chris138,
Did you managed to get the token?
If yes, would you mind to share it here? Thanks

@Mnemo unfortunately not.
My endpoint seems to be wrong or similar. I can’t find any help or proper documentation. :frowning:

@lukio can you answer this one :point_up: , please?