Each example is the inside of main, written in every language API Maker runs : pick yours in the tabs, and every page shows it from then on. The types a call takes (GetAll, DeepItem…) are those of am : from am import GetAll in Python, use am::GetAll; in Rust, import am.GetAll; in Java and Kotlin ; PHP and C# have them without an import, Go names them am.GetAll.
In TypeScript every g.sys call returns a promise : await it. A call without await runs, but its result and its errors are lost. The same in Python (in async def main) and C#. PHP, Go, Rust, Java and Kotlin wait for the answer of each call.
A g.sys call returns the data and throws the errors of the API.
With true as the second argument in TypeScript, or through full in the other languages (g.sys.db.full, g.Sys.Db.Full), it returns the whole envelope { success, statusCode, data, errors, warnings } and never throws : read success yourself.
An error raised ends the call with success: false, the message in errors and its code as the status. A message listed in the errorList of the API can be translated.
letsaveData=awaitg.sys.db.saveSingleOrMultiple({instance:"INSTANCE_NAME",database:'DB_NAME',collection:"COLLECTION_NAME",saveData:{},headers:{}},true);if(!saveData.success)throw[{code:T.EStatusCode.BAD_REQUEST,message:'Your data is not saved!'}];returnsaveData;
save_data=awaitg.sys.db.full.save_single_or_multiple('INSTANCE_NAME','DB_NAME','COLLECTION_NAME',{},headers={})ifnotsave_data.success:raiseErrors('Your data is not saved!',code=400)returnsave_data
$saveData = $g->sys->db->full->saveSingleOrMultiple('INSTANCE_NAME', 'DB_NAME', 'COLLECTION_NAME', new AmObject(), headers: new AmObject());if (!$saveData->success) { throw new AmErrors('Your data is not saved!', 400);}return $saveData;
varsaveData=awaitg.Sys.Db.Full.SaveSingleOrMultiple(newSave("INSTANCE_NAME","DB_NAME","COLLECTION_NAME",newJsonObject()){Headers=newJsonObject()});if(!saveData.Success)thrownewAmErrors("Your data is not saved!",400);returnsaveData;
saveData,err:=g.Sys.Db.Full.SaveSingleOrMultiple(am.Save{Instance:"INSTANCE_NAME",Database:"DB_NAME",Collection:"COLLECTION_NAME",SaveData:am.M{},Headers:am.M{}})iferr!=nil{returnnil,err}if!saveData.Success{returnnil,am.Fail(400,"Your data is not saved!")}returnsaveData,nil
letsave_data=g.sys.db.full.save_single_or_multiple(Save::new("INSTANCE_NAME","DB_NAME","COLLECTION_NAME",json!({})).headers(json!({})))?;if!save_data.success{returnErr(am::fail(400,"Your data is not saved!"));}Ok(json!({"success":save_data.success,"data":save_data.data.row()}))
ApiResponse<Saved>saveData=g.sys.db.full.saveSingleOrMultiple(newSave("INSTANCE_NAME","DB_NAME","COLLECTION_NAME",Map.of()).headers(Map.of()));if(!saveData.isSuccess())thrownewAmErrors("Your data is not saved!",400);returnsaveData;
valsaveData=g.sys.db.full.saveSingleOrMultiple(Save("INSTANCE_NAME","DB_NAME","COLLECTION_NAME",mapOf<String,Any?>()).headers(mapOf<String,Any?>()))if(!saveData.isSuccess)throwAmErrors("Your data is not saved!",400)returnsaveData
import*asTfrom'types';import*asfsfrom'fs';import*aspathfrom'path';asyncfunctionmain(g:T.IAMGlobal){// always write file in the uploads folder which you want to send to user.// you can write other files in any directory which you don't want to send to user.awaitfs.promises.mkdir(path.join(__dirname,'uploads'),{recursive:true});letfilePath=path.join(__dirname,'uploads','myfile.txt');awaitfs.promises.writeFile(filePath,'file 1 content',{encoding:'utf8'});return{// just provide file name which is written to "uploads" directory__am__downloadFilePath:'myfile.txt',__am__downloadFolderFileName:'newName.txt',// download file will have this name.}};module.exports=main;
importosfromamimportGasyncdefmain(g:G):# Write the files to send in the folder uploads ; the other files anywhere else.os.makedirs('uploads',exist_ok=True)withopen(os.path.join('uploads','myfile.txt'),'w',encoding='utf-8')asfile:file.write('file 1 content')return{'__am__downloadFilePath':'myfile.txt',# its name in the folder uploads'__am__downloadFolderFileName':'newName.txt',# the name the file is saved under}
<?phpfunctionmain(AmG$g){// Write the files to send in the folder uploads ; the other files anywhere else.if(!is_dir('uploads')){mkdir('uploads',0777,true);}file_put_contents('uploads/myfile.txt','file 1 content');return['__am__downloadFilePath'=>'myfile.txt',// its name in the folder uploads'__am__downloadFolderFileName'=>'newName.txt',// the name the file is saved under];}
usingSystem.IO;filestaticclassApi{publicstaticasyncTask<object?>Main(Gg){// Write the files to send in the folder uploads ; the other files anywhere else.Directory.CreateDirectory("uploads");awaitFile.WriteAllTextAsync(Path.Combine("uploads","myfile.txt"),"file 1 content");returnnewJsonObject{["__am__downloadFilePath"]="myfile.txt",// its name in the folder uploads["__am__downloadFolderFileName"]="newName.txt",// the name the file is saved under};}}
packagecodeimport("os""path/filepath""apimaker/am")funcMain(g*am.G)(any,error){// Write the files to send in the folder uploads ; the other files anywhere else.iferr:=os.MkdirAll("uploads",0o755);err!=nil{returnnil,err}iferr:=os.WriteFile(filepath.Join("uploads","myfile.txt"),[]byte("file 1 content"),0o644);err!=nil{returnnil,err}returnam.M{"__am__downloadFilePath":"myfile.txt",// its name in the folder uploads"__am__downloadFolderFileName":"newName.txt",// the name the file is saved under},nil}
useam::{Errors,G,Value,json};pubfnmain(g:&mutG)->Result<Value,Errors>{// Write the files to send in the folder uploads ; the other files anywhere else.std::fs::create_dir_all("uploads")?;std::fs::write("uploads/myfile.txt","file 1 content")?;Ok(json!({"__am__downloadFilePath":"myfile.txt",// its name in the folder uploads"__am__downloadFolderFileName":"newName.txt",// the name the file is saved under}))}
importam.G;importjava.nio.file.Files;importjava.nio.file.Path;importjava.util.Map;classApi{staticObjectmain(Gg)throwsException{// Write the files to send in the folder uploads ; the other files anywhere else.Files.createDirectories(Path.of("uploads"));Files.writeString(Path.of("uploads","myfile.txt"),"file 1 content");returnMap.of("__am__downloadFilePath","myfile.txt",// its name in the folder uploads"__am__downloadFolderFileName","newName.txt");// the name the file is saved under}}
importam.Gimportjava.io.Filefunmain(g:G):Any?{// Write the files to send in the folder uploads ; the other files anywhere else.File("uploads").mkdirs()File("uploads","myfile.txt").writeText("file 1 content")returnmapOf("__am__downloadFilePath"to"myfile.txt",// its name in the folder uploads"__am__downloadFolderFileName"to"newName.txt",// the name the file is saved under)}
import*asTfrom'types';import*asfsfrom'fs';import*aspathfrom'path';asyncfunctionmain(g:T.IAMGlobal){return{__am__downloadFileOrFolderPaths:[{fsSource:path.join('folder1','folder2','folder3','data_folder'),// path into uploads folderarchiveDestination:'data_folder',// path in zip file, so data_folder folder will be directly available in zip file.},],__am__downloadFolderFileName:`output.zip`,// download file will have this name.}};module.exports=main;
fromamimportGasyncdefmain(g:G):return{'__am__downloadFileOrFolderPaths':[{'fsSource':'folder1/folder2/folder3/data_folder',# a path in the folder uploads'archiveDestination':'data_folder',# its path in the zip file},],'__am__downloadFolderFileName':'output.zip',# the name the file is saved under}
<?phpfunctionmain(AmG$g){return['__am__downloadFileOrFolderPaths'=>[['fsSource'=>'folder1/folder2/folder3/data_folder',// a path in the folder uploads'archiveDestination'=>'data_folder',// its path in the zip file],],'__am__downloadFolderFileName'=>'output.zip',// the name the file is saved under];}
filestaticclassApi{publicstaticasyncTask<object?>Main(Gg){returnnewJsonObject{["__am__downloadFileOrFolderPaths"]=newJsonArray(newJsonObject{["fsSource"]="folder1/folder2/folder3/data_folder",// a path in the folder uploads["archiveDestination"]="data_folder",// its path in the zip file}),["__am__downloadFolderFileName"]="output.zip",// the name the file is saved under};}}
packagecodeimport"apimaker/am"funcMain(g*am.G)(any,error){returnam.M{"__am__downloadFileOrFolderPaths":[]any{am.M{"fsSource":"folder1/folder2/folder3/data_folder",// a path in the folder uploads"archiveDestination":"data_folder",// its path in the zip file},},"__am__downloadFolderFileName":"output.zip",// the name the file is saved under},nil}
useam::{Errors,G,Value,json};pubfnmain(g:&mutG)->Result<Value,Errors>{Ok(json!({"__am__downloadFileOrFolderPaths":[{"fsSource":"folder1/folder2/folder3/data_folder",// a path in the folder uploads"archiveDestination":"data_folder",// its path in the zip file},],"__am__downloadFolderFileName":"output.zip",// the name the file is saved under}))}
importam.G;importjava.util.List;importjava.util.Map;classApi{staticObjectmain(Gg){returnMap.of("__am__downloadFileOrFolderPaths",List.of(Map.of("fsSource","folder1/folder2/folder3/data_folder",// a path in the folder uploads"archiveDestination","data_folder")),// its path in the zip file"__am__downloadFolderFileName","output.zip");// the name the file is saved under}}
importam.Gfunmain(g:G):Any?{returnmapOf("__am__downloadFileOrFolderPaths"tolistOf(mapOf("fsSource"to"folder1/folder2/folder3/data_folder",// a path in the folder uploads"archiveDestination"to"data_folder",// its path in the zip file),),"__am__downloadFolderFileName"to"output.zip",// the name the file is saved under)}
import*asTfrom'types';import*asfsfrom'fs';import*aspathfrom'path';asyncfunctionmain(g:T.IAMGlobal){// always write file in the uploads folder which you want to send to user.// you can write other files in any directory which you don't want to send to user.awaitfs.promises.mkdir(path.join(__dirname,'uploads'),{recursive:true});letfilePath=path.join(__dirname,'uploads','myfile.txt');awaitfs.promises.writeFile(filePath,'file 1 content',{encoding:'utf8'});return{// You can provide list of files or folders, it will will make zip and send to user.__am__downloadFileOrFolderPaths:['myfile.txt',// file name'someFolder',// folder name],__am__downloadFolderFileName:'zipFile.zip',// this will be zip file name}};module.exports=main;
importosfromamimportGasyncdefmain(g:G):# Write the files to send in the folder uploads ; the other files anywhere else.os.makedirs('uploads',exist_ok=True)withopen(os.path.join('uploads','myfile.txt'),'w',encoding='utf-8')asfile:file.write('file 1 content')return{# Files and folders of the folder uploads : they go out as one zip file.'__am__downloadFileOrFolderPaths':['myfile.txt','someFolder'],'__am__downloadFolderFileName':'zipFile.zip',# the name of the zip file}
<?phpfunctionmain(AmG$g){// Write the files to send in the folder uploads ; the other files anywhere else.if(!is_dir('uploads')){mkdir('uploads',0777,true);}file_put_contents('uploads/myfile.txt','file 1 content');return[// Files and folders of the folder uploads : they go out as one zip file.'__am__downloadFileOrFolderPaths'=>['myfile.txt','someFolder'],'__am__downloadFolderFileName'=>'zipFile.zip',// the name of the zip file];}
usingSystem.IO;filestaticclassApi{publicstaticasyncTask<object?>Main(Gg){// Write the files to send in the folder uploads ; the other files anywhere else.Directory.CreateDirectory("uploads");awaitFile.WriteAllTextAsync(Path.Combine("uploads","myfile.txt"),"file 1 content");returnnewJsonObject{// Files and folders of the folder uploads : they go out as one zip file.["__am__downloadFileOrFolderPaths"]=newJsonArray("myfile.txt","someFolder"),["__am__downloadFolderFileName"]="zipFile.zip",// the name of the zip file};}}
packagecodeimport("os""path/filepath""apimaker/am")funcMain(g*am.G)(any,error){// Write the files to send in the folder uploads ; the other files anywhere else.iferr:=os.MkdirAll("uploads",0o755);err!=nil{returnnil,err}iferr:=os.WriteFile(filepath.Join("uploads","myfile.txt"),[]byte("file 1 content"),0o644);err!=nil{returnnil,err}returnam.M{// Files and folders of the folder uploads : they go out as one zip file."__am__downloadFileOrFolderPaths":[]string{"myfile.txt","someFolder"},"__am__downloadFolderFileName":"zipFile.zip",// the name of the zip file},nil}
useam::{Errors,G,Value,json};pubfnmain(g:&mutG)->Result<Value,Errors>{// Write the files to send in the folder uploads ; the other files anywhere else.std::fs::create_dir_all("uploads")?;std::fs::write("uploads/myfile.txt","file 1 content")?;Ok(json!({// Files and folders of the folder uploads : they go out as one zip file."__am__downloadFileOrFolderPaths":["myfile.txt","someFolder"],"__am__downloadFolderFileName":"zipFile.zip",// the name of the zip file}))}
importam.G;importjava.nio.file.Files;importjava.nio.file.Path;importjava.util.List;importjava.util.Map;classApi{staticObjectmain(Gg)throwsException{// Write the files to send in the folder uploads ; the other files anywhere else.Files.createDirectories(Path.of("uploads"));Files.writeString(Path.of("uploads","myfile.txt"),"file 1 content");returnMap.of(// Files and folders of the folder uploads : they go out as one zip file."__am__downloadFileOrFolderPaths",List.of("myfile.txt","someFolder"),"__am__downloadFolderFileName","zipFile.zip");// the name of the zip file}}
importam.Gimportjava.io.Filefunmain(g:G):Any?{// Write the files to send in the folder uploads ; the other files anywhere else.File("uploads").mkdirs()File("uploads","myfile.txt").writeText("file 1 content")returnmapOf(// Files and folders of the folder uploads : they go out as one zip file."__am__downloadFileOrFolderPaths"tolistOf("myfile.txt","someFolder"),"__am__downloadFolderFileName"to"zipFile.zip",// the name of the zip file)}
asyncfunctiondownloadFileFromBrowser(){constrequestPayload={};constrequestHeaders={};constresp=<any>awaitthis.http.post(`API Maker custom API endpoint`,requestPayload,{headers:requestHeaders,responseType:<any>'text',observe:'response',}).toPromise();constfileName=resp.headers.get('content-filename');awaitthis.downloadFileFromBlob('application/zip',resp.body,fileName);returnresp;}asyncfunctiondownloadFileFromBlob(contentType,base64Data:any,fileName){consta=document.createElement('a');document.body.appendChild(a);a.style.display='none';letblob;if(base64DatainstanceofBlob){blob=base64Data;}else{constbase64Response=awaitfetch(`data:${contentType};base64,`+base64Data);blob=awaitbase64Response.blob();}consturl=window.URL.createObjectURL(blob);a.href=url;a.download=fileName;a.click();window.URL.revokeObjectURL(url);}
It reads the tenant in g.req.params, and the APIs it calls with g.sys.db and g.sys.system work on the database of that tenant: the header is passed on, and each instance finds the tenant in its own tenants table.
instance: 'crm::globex' names another tenant for one call, and an empty tenant header names the structure database. See Custom APIs of a multi-tenant instance.
import*asTfrom'types';asyncfunctionmain(g:T.IAMGlobal){consttenant=g.req.params.tenantUsername;// 'acme'constcustomers=awaitg.sys.db.getAll({instance:'crm',database:'crm',collection:'customers'});// from the database of acmeconstcustomersOfGlobex=awaitg.sys.db.count({instance:'crm::globex',database:'crm',collection:'customers'});return{tenant,customers,customersOfGlobex};}module.exports=main;
fromamimportGasyncdefmain(g:G):tenant=g.req.params.tenantUsername# 'acme'customers=awaitg.sys.db.get_all('crm','crm','customers')# from the database of acmecustomers_of_globex=awaitg.sys.db.count('crm::globex','crm','customers')return{'tenant':tenant,'customers':customers,'customersOfGlobex':customers_of_globex}
<?phpfunctionmain(AmG$g){$tenant=$g->req->params->tenantUsername;// 'acme'$customers=$g->sys->db->getAll('crm','crm','customers');// from the database of acme$customersOfGlobex=$g->sys->db->count('crm::globex','crm','customers');return['tenant'=>$tenant,'customers'=>$customers,'customersOfGlobex'=>$customersOfGlobex];}
filestaticclassApi{publicstaticasyncTask<object?>Main(Gg){vartenant=g.Req.Params.GetString("tenantUsername");// "acme"varcustomers=awaitg.Sys.Db.GetAll(newGetAll("crm","crm","customers"));// from the database of acmevarcustomersOfGlobex=awaitg.Sys.Db.Count(newCount("crm::globex","crm","customers"));returnnew{tenant,customers,customersOfGlobex};}}
packagecodeimport"apimaker/am"funcMain(g*am.G)(any,error){tenant:=g.Req.Params().String("tenantUsername")// "acme"customers,err:=g.Sys.Db.GetAll(am.GetAll{Instance:"crm",Database:"crm",Collection:"customers"})// from the database of acmeiferr!=nil{returnnil,err}customersOfGlobex,err:=g.Sys.Db.Count(am.Count{Instance:"crm::globex",Database:"crm",Collection:"customers"})iferr!=nil{returnnil,err}returnam.M{"tenant":tenant,"customers":customers,"customersOfGlobex":customersOfGlobex},nil}
useam::{Count,Errors,G,GetAll,Value,json};pubfnmain(g:&mutG)->Result<Value,Errors>{lettenant=g.req.params()["tenantUsername"].clone();// "acme"letcustomers=g.sys.db.get_all(GetAll::new("crm","crm","customers"))?;// from the database of acmeletcustomers_of_globex=g.sys.db.count(Count::new("crm::globex","crm","customers"))?;Ok(json!({"tenant":tenant,"customers":customers,"customersOfGlobex":customers_of_globex}))}
importam.Count;importam.G;importam.GetAll;importam.JsonObject;importjava.util.List;classApi{staticObjectmain(Gg){Stringtenant=g.req.getParams().getString("tenantUsername");// "acme"List<JsonObject>customers=g.sys.db.getAll(newGetAll("crm","crm","customers"));// from the database of acmelongcustomersOfGlobex=g.sys.db.count(newCount("crm::globex","crm","customers"));returnJsonObject.of("tenant",tenant,"customers",customers,"customersOfGlobex",customersOfGlobex);}}
importam.Countimportam.Gimportam.GetAllfunmain(g:G):Any?{valtenant=g.req.params.getString("tenantUsername")// "acme"valcustomers=g.sys.db.getAll(GetAll("crm","crm","customers"))// from the database of acmevalcustomersOfGlobex=g.sys.db.count(Count("crm::globex","crm","customers"))returnmapOf("tenant"totenant,"customers"tocustomers,"customersOfGlobex"tocustomersOfGlobex)}