This article suggests to you some patterns to create REST API applications using IRIS.
Note: source code in https://github.com/yurimarx/movie
Class Pattern to the REST Application
To begin, see my suggestion for classes needed to create IRIS API applications:
- IRISRESTApplication: CSP.REST class that will be the central controller for all REST requests and responses processed by the business services.
- BusinessService: class with a business topic implementation. It can use one or more Persistent Domain Classes to persist and query data required by the business topic requirements.
- Persistent Domain: persistent class to manage a SQL table.
Prereqs
- VSCode;
- Docker Desktop;
- InterSystems ObjectScript Extension Pack.
Class Diagram to the Sample Application
I will create a Movie Catalog application to demonstrate the patterns suggested in the article:
Note: thanks to the https://openexchange.intersystems.com/package/iris-rest-api-template application. It was the base to this tutorial.
Setup the Sample Application
1. Create a folder movie in your file system. Open this folder in a new VSCode window.
2. Create the Dockerfile file inside movie folder to run IRIS Community edition into a Docker container instance. Content:
3. Create the docker-compose.yml file inside movie folder to allows you run your docker instance and other instances together (not in this sample, but it is a good practice run from docker-compose instead dockerfile. Content:
4. Create the iris.script file inside movie folder to do some actions before run IRIS. This file is important to do custom terminal actions necessary for the application, like disable password expiration. Content:
5. Create the module.xml file inside movie folder to install and run your application using ZPM. This file is important to do the application endpoint configuration and install swagger-ui (web app used to run and test your API using swagger file). Content:
You can see CSPApplication tag, used to run the application API in the /movie-api URI and enable or disable password to consume the API.
6. Create the LICENSE file inside movie folder to setting the license of your application. Content:
7. Create the README.md file inside movie folder to document your application to the users using markdown language. Content:
8. Create .vscode folder inside movie folder. Create settings.json file inside .vscode folder to configure server connection between VSCode and your IRIS instance. Content:
9. Create the folder src inside movie folder to put your source code folders and files.
10. Create dc folder inside src folder. This is a convention when your build projects to the InterSystems Developer Community, otherwise is not necessary.
11. Create movie folder inside dc folder. This folder will be the folder to your objectscript classes.
12. Create our first class, MovieRESTApp.cls file, inside src\dc\movie folder. This file will be the IRISRESTApplication class. Content:
Note 1: The class extends CSP.REST to be used as the REST Endpoint.
Note 2: the parameter chaset is used to encode requests and responses with UTF-8.
Note 3: the CONVERTINPUTSTREAM is used to force the request content in the UTF-8, without this you can have problems with special latin chars.
Note 4: CONTENTTYPE is used to declare the content using JSON, not XML.
Note 5: HandleCorsRequest = 1 is necessary to allows you consume the API from other servers different from the IRIS server.
Note 6: Routes are used to declare API URI to each class method.
Note 7: SwaggerSpec from CSP.REST class allows you generate the API swagger (API web documentation) content.
Now you have the following folders and files:
13. Open VSCode Terminal (menu Terminal > New Terminal) and type:
docker-compose up -d --build
This will build the docker instance and run it.
14. Test your API with Swagger-UI. In the browser and type: http://localhost:52773/swagger-ui/index.html. Pay attention to the address bar (fix the url, if necessary to correct address)
Connection beetween VSCode and IRIS
1. Click in the ObjectScript bar (in the VSCode footer)
2. Select Toogle Connection in the Top:
3. Check the connection status into ObjectScript Explorer (you will be able to see folders and classes created):
Persistent Classes to the Movie Catalog Application
In this section we will create the persistent domain classes to store and query the business data. See the DBeaver Diagram:
1. Create the folder model inside src\dc\movie folder.
2. Create the Actor.cls file inside model folder. Write the content:
3. Create the Movie.cls file inside model folder. Write the content:
4. Create the MovieCategory.cls file inside model folder. Write the content:
5. Create the Casting.cls file inside model folder. Write the content:
See the created files:
Note 1: Parameter %JSONREFERENCE = "ID" allows return ID value inside JSON response.
Note 2: Property actorId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ] and the other similar properties are used to return class+id into JSON response.
Note 3: (VALUELIST = "1,2") set possible values to 1 or 2 only.
Note 4: ForeignKey MovieFK(movie) References dc.movie.model.Movie() and similar are used to create a SQL foreign key reference.
Note 5: Index CastingIndex On (movie, actor) [ Unique ] and similar are used to not allows duplicate values combining properties in the On (movie and actor).
Note 6: I'm using Camel Case to property names because a best practice for JSON attribute names.
Business Service Classes to the Movie Catalog Application
In this section we will create the classes with business logic (methods to do persistence, query and calculations).
1. Create the service folder inside src\dc\movie.
2. Create CrudUtilService.cls file inside service folder. Write the content:
3. Create MovieService.cls file inside service folder. Write the content:
4. Create MovieCategoryService.cls file inside service folder. Write the content:
5. Create ActorService.cls file inside service folder. Write the content:
6. Create CastingService.cls file inside service folder. Write the content:
7. Update the file MovieRESTApp.cls to create paths to all new service class methods. Write the content:
8. The files and folders to the final project are:
9. Test your new methods acessing http://localhost:52773/swagger-ui/index.html.
Note 1: REST paths are following business topic in plural with /id when we need pass id to the entity and camel case to paths to.
Note 2: We use verb GET to queries, POST to new records, PUT to update record and DELETE to delete a record.
Note 3: In <Route Url="/movies/casting/:id" Method="GET" Call="GetMovieCasting" /> I used /casting indicating a second purpose (get the movie and it casting). This method runs ToJSON(), because is a DynamicArray ([]) with Dynamic items ({}).
Note 4: I created the CrudUtilService class utility to do generic CRUD methods, following the Dont Repeat Yourself principle.
Enjoy this tutorial!
Hi Yuri
You didn't use GoJS by any chance for the UML etc... If you look in the General Section of Discord I have written a chunk of stuff about GoJS and how a developer could build the necessary data collectors into their classes and then having but the data sets render the diagrams through GoJS
Thanks for the tip! I did use StarUML, but in the next time I will consider GoJS
Great article.
Some comments on formatting:
On the article itself my only issue is you create 5 methods per class:
That's a lot of code even for 4 classes, but what about a case where there are 10 classes? 50? 100? Generally I would recommend writing 5 methods which would process objects of any allowed class (see RESTForms2).
Fixed and improved, thanks!!!
Hi Yuri
I forgot to mention that I agree with Eduard that your article is excellent.
Nigel
Thanks!!!
Excellent work @Yuri Marx, lots of useful details for the reader! I like DRY too :-)
Thanks @Luca Ravazzolo