Pierre LaFay · Aug 6, 2023 go to post

Thanks Julius

I also found the %OnNew() method for consytructor of the object

Pierre LaFay · Aug 11, 2023 go to post

Thanks Eduard,

That's my first try  (doesn't work, global ^Pierre not set with login)

It seems that method in my class doesn't override the methods on %CSP/REST.

This the beginning of my class which extends %CSP.REST, Do I miss something ?

Class Bna.Api.Bna2024 Extends%CSP.REST
{
Parameter HandleCorsRequest = 1;Parameter CHARSET = "UTF-8";Parameter CONTENTTYPE = "application/json";
XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/lists" Method="GET" Call="GetLists" />
    <Route Url="/me" Method="GET" Call="GetUserInformations" />
    <Route Url="/reset-password" Method="POST" Call="ResetUtilisateurPassword" />
    <Route Url="/utilisateurs" Method="GET" Call="GetUtilisateur" />
    <Route Url="/utilisateurs" Method="POST" Call="CreateUtilisateur" />
    <Route Url="/utilisateurs" Method="PATCH" Call="ModifyUtilisateur" />
    <Route Url="/utilisateurs" Method="DELETE" Call="DeleteUtilisateur" />
</Routes>
}

ClassMethod Login(skipheader As%Boolean = 1) As%Status [ ProcedureBlock = 0 ]
{
    Set^Pierre("login")="on login (by overrided Login method)"Return##super(skipheader)
}
...
Pierre LaFay · Aug 11, 2023 go to post

Hi Ashok,

Thanks for your reply, overriding OnPreDispatch Method doesn't not work with login, refresh, logout (special routes) but with my own routes it's work. So It's not a solution for me

This the beginning of my class which extends %CSP.REST,  I missed something ?

Class Bna.Api.Bna2024 Extends%CSP.REST
{
Parameter HandleCorsRequest = 1;Parameter CHARSET = "UTF-8";Parameter CONTENTTYPE = "application/json";
XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/lists" Method="GET" Call="GetLists" />
    <Route Url="/me" Method="GET" Call="GetUserInformations" />
    <Route Url="/reset-password" Method="POST" Call="ResetUtilisateurPassword" />
    <Route Url="/utilisateurs" Method="GET" Call="GetUtilisateur" />
    <Route Url="/utilisateurs" Method="POST" Call="CreateUtilisateur" />
    <Route Url="/utilisateurs" Method="PATCH" Call="ModifyUtilisateur" />
    <Route Url="/utilisateurs" Method="DELETE" Call="DeleteUtilisateur" />
</Routes>
}
ClassMethod OnPreDispatch(pUrl As%String, pMethod As%String, ByRef pContinue As%Boolean) As%Status
{
    Set^Pierre("login")="on login (by overrided method pre dispatch)"return$$$OK
}
...
Pierre LaFay · Aug 13, 2023 go to post

Hi ashok,

There is the same issue, Page method in my %CSP.REST subclass is not called...

Pierre LaFay · Aug 20, 2023 go to post

Hi Eduard,

Many thanks for yours answers

My app config is same of you, except I use JWT token authentification (UnKnownUser doesn't have %ALL) :

Pierre LaFay · Aug 20, 2023 go to post

I found a way by %request.Data("Top",1), but in this case, I get parameters one by one.

Is a method to get all my parameters in an object or an array exists ?

Pierre LaFay · Aug 21, 2023 go to post

Hi Ashok,

Thank you for your answer, I understand and will apply looping by Next in Data.

However, I don't know how to merge the entire %request.Data into local array and use string function.

I'm sorry for asking questions that should be obvious, but I'm new to Iris for REST Api...

Pierre LaFay · Aug 21, 2023 go to post

Hi Eduard,

Thanks for this utility method. I think I will use it for debugging

Pierre LaFay · Nov 13, 2023 go to post

Thanks George,

It's not what i search, I would have the type, not test if is one type.

Pierre LaFay · Nov 14, 2023 go to post

Thanks Julius,

It was exactly what i needed. My goal was to copy properties from a dynamic object to a persistent object, but in dynamic object for reference, I have only id, not a ref.

So i made this : (main class)

Class Bna.Utils.DynToPersistent Extends%RegisteredObject
{

Property DynObject As%Library.DynamicObject;Property PersistentObject;

Method %OnNew(dynObject As%Library.DynamicObject, persistentObject) As%Status
{
    Set..DynObject = dynObject
    Set..PersistentObject = persistentObject
    Return$$$OK
}

Method copyDynToPersistent()
{
    set pClass = ..PersistentObject.%ClassName(1)
    Set iterator = ..DynObject.%GetIterator()
    while iterator.%GetNext(.pProp, .pValue) {
        Set pType = ##class(Bna.Utils.Common).GetPersistentObjectPropertyType(pClass,pProp)
        Set isRef = ##class(Bna.Utils.Common).PersistentObjectPropertyTypeIsReference(pType)
        if isRef {
            set value = $ZOBJCLASSMETHOD(pType, "%OpenId", pValue)
        } else {
            set value = pValue
        }
        Set$ZOBJPROPERTY(..PersistentObject, pProp) = value
    }
}

}

(utility methods) :

ClassMethod GetPersistentObjectPropertyType(pClass As%String, pKey As%String) As%String
{
	set def=##class(%Dictionary.PropertyDefinition).%OpenId(pClass_"||"_pKey)
	if def Return def.Type
}

ClassMethod PersistentObjectPropertyTypeIsReference(pType) As%Boolean
{
	if$EXTRACT(pType,1,1) = "%" { Return0 }
	else { Return1 }
}

 I think my test for reference detection can be light, but enough in my context

Pierre LaFay · Dec 13, 2023 go to post

You can access your elements by this way (for the example, your object is named jsObj)

w jsObj.%Get(0).thingone,!
Red
w jsObj.%Get(0).thingtwo,!
Green
w jsObj.%Get(1).thingone,!
Blue
w jsObj.%Get(1).thingtwo,!
Yellow

Caution : For dynamic array, first element is indexed by 0, not 1 like ObjectScript standard arrays

Pierre LaFay · Dec 18, 2023 go to post

Hi Zhang,

In the portal : System/Security/Roles you can create your own role like "myUserRole".

When created you have in the role definition a tab "Sql Tables".

In this tab you can add the tables which the role can access.

If you assign the created role to a user, he can access the tables.

hardcopy of the Sql Tables Tab in System/Security/Roles (in french)

Pierre LaFay · Dec 21, 2023 go to post

To complete @Ashok Kumar T answer, the good way to get file content :

Set source = %request.GetMimeData("file")
        Set destination=##class(%Stream.FileBinary).%New()
        Set destination.Filename="/opt/irisbuild/output/"_source.FileName
        set tSC=destination.CopyFrom(source) //reader open the fileset result=destination.%Save()
Pierre LaFay · Dec 21, 2023 go to post

I asked intersystems for the same question, the solution is to upgrade to 2023.3 (2023.1 has issue in error reporting in Atelier)

Pierre LaFay · Dec 23, 2023 go to post

Thanks for this article,

Just what I need to start using python (I use Objectscript since 12 years), and examples is more efficient for me.

Pierre LaFay · Dec 26, 2023 go to post

You can :

Create an abstract class with a method that successively calls:
FileCompact() and ReturnUnusedSpace() from the class SYS.Database

Then you can add in the task manager a new task (type RunLegacyTask) which calls your method

Before doing this, I advise you to make a backup of your database or a snapshot of your machine if it is a VM

Pierre LaFay · Dec 26, 2023 go to post

I am currently developing a REST API backend and I have chosen to systematically use classes, because mixing csp files and classes seems to me to harm the maintainability of the code.
Furthermore in this case, a database backup contains everything, I don't have to worry about separate files.
This is just my opinion :)

Pierre LaFay · Jan 3, 2024 go to post

I suggest you create a json object in an objectscript method and call this method with an http request from your javascript to retrieve the object

Pierre LaFay · Jan 6, 2024 go to post

Hi @David Hockenbroch

I think I've found another way to protect a route.
I'm not protecting the route itself, but the method it points by using [ Requires = "myResource:Use" ] on the called method:

 

/// Sample APIClass Test.Api Extends%CSP.REST
{

 XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
 {
	<Routes>
		<Route Url="/test" Method="GET" Call="Test" />
	</Routes>
 }

 ClassMethod Test() As%Status [ Requires = "myResource:Use" ]
 {
  Do##class(%REST.Impl).%WriteResponse("api method test : OK")
  Return$$$OK
 }
}
Pierre LaFay · Jan 11, 2024 go to post

If your goal is to delete this file one time you can do it with one of theses methods :

You can delete the file by using terminal : (the sudo command set you with all privileges on files)

sudo rm /tmp/test/test1.txt

Or from an Irii terminal

!sudo rm /tmp/test/test1.txt

If not can you tell me how you create it, and give the result of this command ?

ls /tmp/test.txt -lh

or (in Iris terminal 

!ls /tmp/test.txt -lh
Pierre LaFay · Jan 12, 2024 go to post

I think you'll get a lot more help if you give the details of your error.
How do you get this error?
In what context ?
On which version of Iris or hidden ( w $ZV to obtain version information)
Furthermore, you are on the site of a volunteer community, saying hello also helps to get help.

Pierre LaFay · Jan 12, 2024 go to post

You are in the right place to have the information you want:

On this web application (https://community.intersystems.com/) you have access to
Resources intersystems on l-the left bar in community t tab where you can find a kit to start using Iris (in a container or not), I suggest you docker container for a faster setup


The learning tab will provide access to course videos
The Documentation tab to the product documentation with a search function (The documentation also includes very useful how-to sections)
The open-exchange tab offers example applications or utility classes that can inspire or save time during your projects.

And of course the community tab. The people here are all kind and will try to help you. You will also find articles full of useful information there.

So you can ask your questions as you learn.

Last but not least: Welcome to the Intersystems community !!