Apex Designer has always been a great choice for building apps that integrate other APIs or apps, and now that is easier than ever. This video shows how to connect to an external REST API and generate a business object automatically to handle the response data. I'll let Dave take it from here...
Video Transcript
This is Dave from Apex. I'm excited to show you a new capability within design in context that lets us create business objects directly from a REST API. So a normal project would have business objects like supplier that are connected to some kind of database, in this case a Postgres database. And in this application I've added a second data source called the Box REST API. That data source is configured with environment variables that give the API keys necessary to access that REST API. When we click on that data source, we see a page that lets us experiment with the data source and try the API out. So here I'm just doing a get operation on folders with a folder ID and I see all of the information that comes back for that. We also see that there's a new button being enabled called Generate Business Object.
When I click that, a bunch of new information shows up. First of all, in the available properties column, we see properties that have been inferred from different parts of the sample response from the API. And I can take those properties and add them in to the selected list that I'll create on my business object. So I'm going to put in ID, name, I'm putting in created_at, but I don't like the "_at" convention, so I'm just going to take the "_at" off of there, put in modified, same kind of trick - take off "_at". And finally I'm going to put description in. I want that right after name. And you notice this one came in as a string, but I'm going to switch that to a multi-line string. And I'm also going to hide this one so that it is not shown in tables. So now I have the set of properties that I want easily selected from the big list that they gave us to work with.
Now over in the fifth column, we have the selected behaviors. So "find" - that makes sense, we'd want to find folders. "Find by id" - that also makes sense. In this particular example we're not going to do "find by parent" because we just will have folders - one layer of folders with files inside. The "create", "update" and "delete" all make sense.
I'm going to key in the name for my new business object and click create. What's happening now is it has created the business object and reloaded the page with REST API configuration for that business object. So you can see here two rows. The top row is about a request. We have the input, which in this case is the ID because that is what the behavior is defined by: ID. And in the middle we have a request template. That template is expressed in a wonderful templating language called Jsonata. If you've not checked it out, go to Jsonata.org and try out their playground.
In this case, we can click the play button and we see that it takes this input, concatenates it onto folders to get a request that looks like this. That request then is sent, and here is the response very much like we saw on the other page. Here is a response template, which gives us the generated output. So that's perfect. Let's go on and do the next operation. Let's try a create.
First of all, I don't really want to pass in the created and modified because that will get set automatically by Jsonata or by the Box API. So [removing those] should probably do it if I try that out. You notice here that we get an error. It's saying that there's a parent missing when we're trying to create our folder.
We can flip over to the Box REST API reference, and take a look at their example for creating a folder. You'll see that every folder has a parent and ID, and zero is the root folder. So we're not dealing with folder hierarchy (in our application). So we'll just stick this [parentId = 0] in here, right click to reformat looks nice and clean, try that out. And it says we already have one by that name. So let's try this one. And finally we've created one. Here's the response that came back. And for the create operation, all we need to do is pass back the ID so it pulled it out successfully. We'll copy this ID here and then use it in a couple of other tests.
Part of the reason that we use this kind of request response template is there are slight nuances to every REST API, and they're never quite following the exact pattern that you want. This is another example. By default, we've set this to be a "patch" operation, but you'll see when we run this that it says the method is not allowed. And if we flip back over here [to the documentation], we find out that updating a folder is a "put". Now in most APIs, patch is how you would update individual properties of a given object, but in their case they want put so that's fine. That's what we'll do. And here we go. We have now updated our folder. Let's copy this ID again. Go on to delete. We'll make sure that delete is working for us and it is. And that leaves us only one, which is fine.
Now, most of the time a "get" on folders should work. That would be the normal rest API pattern. But you see here, it gives us an error message back from their API that says we're missing the path. So if we go back over here, we see that there isn't really a get of folders. There is just get items in a folder. So it wants to have a folder id. And if you're getting the root folders, it would look like this. So we'll just copy that text, paste it into our template here and see if this one works. Okay, that's better. We have one entry in here. We see that folder, demo folder. That was the one that existed before we started. But we notice over here that the output has the right number of entries but doesn't seem to have the right object. Well, that's because this response is not an array, as is commonly the case. This one has entries as an object, a key within the object that includes the array. So we can just stick that into our template like this, right click to reformat and test it.
That looks pretty good, except we notice that we have ID and name, but we don't have description created or modified. None of that seems to be here. So again, you just flip back to their REST API [reference] and look at this request. And we scroll down a little bit. We see that we can actually call out which fields we want brought back. So let's go add that in. It's in the fields Query parameter. We'll just stick this in: Fields equals ID, name, description, created_at (remembering that we're expressing it in their naming convention), modified_at. That should be everything that we need.
Now we see our modified. Apparently there is no created because I mistyped that. There we go. Now we have everything. Id name, description, created and modified. So at this point, our rest API is fully configured and tested. You notice up on the top right, it's been keeping track of the changes. The changes have been made in Apex Designer, but we need to click this button to regenerate the server side code and the client side code for this particular application. So it's now building that API and starting the application. And when we reload the page, we will be able to go to the folder page. Now here, this business object has these properties. Those are the ones we created. This is the configuration that we just looked at. There aren't any pages or components yet.
So let's go ahead and add a page to be able to see our folders. So this is an objects page which manages objects in a table. So folder is the business object, page name is folders. And the path is slash folders. So if we create this page, it's going to create the page, generate the code, rebuild the application. And when that rebuild is complete, we can reload the page and we will see the page in action. And there is our folder.
We have this nice refresh button here that recalls the API. We can click add new folder and you see created and modified are listed here. Maybe that's not exactly what we were thinking. So we can go into this page and this add button and to do a couple of changes. So maybe we want to exclude "created" and "modified" from the create dialog, and maybe we want to make "name" required. There we go. And if we regenerate this page, let's see if that has taken effect. Sure has. Now we just see name and that name is required.
We can go a step further here. If we click on one of these folders, you may have seen that just momentarily before that, when I click on this, it says we don't really have a page for that path, but that we can add one over here. We can come in here and say add inside this one. Maybe a page for an individual object with fields on it. Let's add that in for folder and create that.
Now, after the page is done generating and the app reloads codes, we will see our page in action. So now we have this where we can rename our folder, and that calls the rest API to change the name of the folder. We also can go into the application and delete this folder. Confirm and it has redirected us back here to the folder page.
So there in just a few minutes you've been able to:
- Explore an existing API
- Generate a business object definition from that API
- Test the various crud operations, create, read, update, delete
- Create the user interfaces for managing that business object using design in context
So I hope you enjoyed that and I look forward to your feedback on this cool new feature.