For my final Hacktoberfest contribution I worked on a project called Bytechef. Bytechef is a low-code API integration and workflow automation platform. It lets you interact with a large list of supported services through their APIs by adding and connecting various components to create control flows that can use the responses from the APIs.
bytechefhq / bytechef
Open-source, low-code, extendable API integration & workflow automation platform. Integrate your organizations or your SaaS product with any third party API
API integration and workflow automation platform
Website - Documentation - Discord - Twitter
UPDATE: ByteChef is under active development. We are in the alpha stage, and some features might be missing or disabled.
What is ByteChef?
ByteChef is an open-source, low-code, extendable API integration and workflow automation platform. ByteChef can help you as:
- An automation solution that allows you to integrate and build automation workflows across your SaaS apps, internal APIs, and databases.
- An embedded solution targeted explicitly for SaaS products, allowing your customers to integrate applications they use with your product.
Key Features
- Intuitive UI Workflow Editor: build and visualize workflows via the UI editor by dragging and dropping components and defining their relations.
- Event-Driven & Scheduled Workflows: automate scheduled and real-time event-driven workflows via a simple trigger definition.
- Multiple flow controls: use the range of various flow controls such as condition, switch, loop, each, parallel, etc.
- Built-In Codeβ¦
My task was to add a new feature to a component for a database service called Baserow. The feature I had to work on was an "action" (i.e. a function of the component) that allowed the component to update a row in the database.
Baserow - Update Row action #1645
Implement the Update Row action for the Baserow component to allow users to modify specific rows within a table in their Baserow database.
Action properties:
- table id - id of the table for which you want to update a row
- row id - id of the row you wish to update
- user_field_names - A boolean indicating whether the field names returned by this endpoint should be the actual names of the fields
- fields - a map of fields and their new values for the table. This property specifies the data to be updated in the row, allowing users to change multiple fields in a single operation.
Ouput:
- row - updated row object containing all the data fields and values associated with the row in the specified table
Documentation Reference: https://baserow.io/api-docs
</div>
<div class="gh-btn-container"><a class="gh-btn" href="https://github.com/bytechefhq/bytechef/issues/1645">View on GitHub</a></div>
I'd used Java very minimally before signing up for this issue. I'd only ever done tiny JavaFX programs as part of a school course, but I'd been wanting to learn more. I had been learning a little bit of it on my own time so I had some level of familiarity with concepts like packages, access modifiers, dependencies, and Gradle, which is the build tool used by the project. Knowing these definitely made it a lot less intimidating going into this project. I understood the project structure because I'd learned how Gradle projects consist of subprojects and subpackages each with different build configurations.
My classmate Arina noticed we were both working on the same project, and she was kind enough to give me some pointers by linking to the developer documentation for adding a component, and to an action that had already been defined for the component, which meant I didn't have to look through the repository myself to find the relevant files/directory. But if I had to, I would've used git grep
, GitHub's code search or IntelliJ's search. I did use git blame to check out the history of the component I was going to work on and saw that it was all developed in one commit.
The project's contributing docs were very easy to follow with detailed instructions laid out step by step. But the project appeared to be very young - I noticed a few README files that just said // TODO
.
I tried to compile and run the program before I made my changes to see how it worked, but it was a rough process. Here's a glance at the notes I took:
After it finished compiling (having taken over an hour), I ran it so I could check out the existing component. I tried making an account to use the client but it wouldn't let me, so I went back to the contributing doc and found that it comes with an admin account that can be used for development, which I think is created when you run docker-compose.
Once I was logged in, I tried making a Baserow component, but the client was a bit slow so I accidentally made a duplicate. When I tried deleting it, the client froze, so I hit refresh, and started getting server errors and the client timed out. I tried restarting the server and client but it was taking a long time - seemed to me like it was going to take an hour again. After waiting for about 16 minutes I called it a night and decided I'd work on it later.
4 days later
I was dreading returning to this project and having to deal with the hour long compilation time but with Hacktoberfest nearing it's end I didn't have much of a choice. So imagine my surprise when the project built without errors and was up and running in less than five minutes. What changed? I have no idea.
So I hopped on the client and found the Baserow component.
Figure - The Baserow component and the existing actions on it
To add the Create Row action, I needed to look at the Baserow API documentation, which was linked to me by the maintainer. I had to make a Baserow account to view the docs which I thought was kind of odd but it wasn't a huge deal either.
So I tested the existing action, "Create Row", and ran into a bug where the whole page turned into an error message. I thought I entered an unexpected value but I'd later discover this bug was already being tracked by a separate issue unrelated to mine.
On a subsequent test attempt the Create Row action succeeded, so I decided it'd be a good candidate to study to try and understand how actions are created. I followed along by cross-referencing the issue, the existing action, and the contributing docs.
I learned that actions were created by defining the input parameters required, the output schema, and a method which defined the actual process the action performed.
In the Create Row action, I saw there was a method to get the fields for a row of the table, which was used to define the input parameters. I realized I could use this in my action, but it was named as if it was only intended for use for the Create Row action. I thought it made sense to use, so I went ahead and used it and decided I'd let the maintainers know.
When reading the Baserow API docs I learned that to update a row you use an HTTP method called "PATCH", which I didn't even know existed. A PATCH is like a PUT but instead of replacing the resource it partially changes it. Interesting stuff.
So I got to actually writing my action, and I was able to lift pretty much the entire code from the existing action. I only had to make slight adjustments to the parameters it accepted (I added a row ID to identify the row to update), the output schema, and the method it called (changed the endpoint and HTTP method). To allow for the row ID I had to add a constant to a file in the constant/
subdirectory which contained all of the constants related to the Baserow component.
I noticed all of the existing source code files had a license header, so I copied it into mine too. I organized my imports, formatted my code, and it was time to manually test it.
At this point I noticed the description for the Create Row action (the one that already existed) was wrong - it said it creates a row in a sample database in Baserow which it referred to by name instead of just saying you can create a row. I made a note to mention this to the maintainers too:
Figure - Incorrect description for Create Row component
My action showed up in the client and visually everything looked good:
The title and description showed up:
The properties (i.e. input parameters) showed up:
The workflow ran successfully and I received a successful response:
And the table was updated in my Baserow account:
I was satisfied with my changes so I went ahead and ran the formatter and tests, but the tests failed, because one of the tests expected the Baserow Component to only have one action on it. I updated the test to accommodate my new action, and ran a script which automatically generated documentation for the component. On rerunning the tests, they passed, but I still had to add a unit test for my action. I looked at the unit test for the existing component and was left scratching my head. I decided I'd made decent progress, so I called it a day, opened a draft PR, and let the maintainer know about the issues I noticed.
The next day
Even though the existing test looked scary, I didn't really have much choice but to add one for my action too, so I went back and tried to comprehend what was going on in the existing test. I looked a little bit into the testing libraries used - JUnit Jupiter and Mockito. I attempted to break it down bit by bit and used an LLM to help me understand what was going on on each line. But to be honest, I still only had a vague understanding of what was going on. I knew I was mocking the Baserow API and calling my action's method on it, but that was the extent of my understanding.
Apparently though, it was good enough. I marked my PR ready for review, and the maintainer accepted my changes! They provided some feedback - I forgot to follow some parts of the contributing flow even though I'd read them. For next time, I should review the contributing docs before creating the pull request.
Create Update Row action for Baserow component #1656
Fixes #1645
- New feature (non-breaking change which adds functionality)
- This change requires a documentation update
- Tested with BaserowComponentHandler definition test, which was updated to accommodate the new action.
- Manually tested action through client:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- No comments deemed necessary since the existing action doesn't include comments either
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
I found the initial setup and writing the test to be the most intimidating parts of this issue. Actually adding the feature was a breeze in comparison. But what I found really cool about this issue was that I'd been able to contribute to a project in a language I didn't know that well, thanks to their well-maintained docs and easy-to-understand code.
And that was my last PR for Hacktoberfest 2024! Recap post coming soon!
Top comments (0)