Contributing guide#
SplitBit is a cost-keeping app for friends and households, similar to the likes of splitwise, tricount, etc except free and open source. It’s ISDC’s first project, and it has been chosen on the grounds that it illustrates a perfect use case for a standard client-server application with multiple front-ends and a REST API server.
To start contributing to the project, we need to set up the development environment, i.e. get all the programs/tools required to compile and run it.
NOTE: I highly advise you using a Linux/Unix-based (hence macOS is also fine) system for your development needs. As a B.Sc. student, you have received the school laptop that runs Ubuntu. Try to do the development on it. If you insist on using Windows you can use WSL or for a purely Windows development, you can download scoop, a so-called package manager (analogous to apt on Linux) to download the necessary tooling more easily. MacOS also has one and it’s called homebrew. The rest of the guide assumes you have one of those installed for your respective platform.
The first step will be to install a version control system. The most popular being git and that’s what we’re also using to manage development over time.
Install git by#
sudo apt install git
for Linuxbrew install git
for macOSscoop install main/git
for Windows Non-WSL
Useful git resources:
- https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository
- https://learngitbranching.js.org/
Now that you have git, you are able to download the files of the SplitBit project, visit https://github.com/ISDC-Helsinki/splitbit, click the < > Code
button and copy to clipboard the link. Next run git clone https://github.com/ISDC-Helsinki/splitbit.git
in your terminal to copy the code repository to your computer.
The root of the project is divided into multiple subdirectories and contains two notable files:
android/
contains the native android app source code.ios/
contains the native iOS app source code.server/
contains the golang backend code.web/
contains the web-client source code.openapi.yml
is probably the most important file, specifying the API contract between the client and server components of the application. This file defines the various endpoints, their HTTP methods, request/response payloads, and other metadata that allows the frontend and backend to communicate effectively.README.md
is a text file giving a small overview of the project and how to set it up. The following part is largely based on it and if this article goes out of date, the README will always contain the most up-to-date guide on how to set the project up.
Schema-driven what?#
The development is openapi schema-driven making the openapi.yml specification file the single source of truth for the API. This allows us to make heavy use of code generation, yielding us effortless, type-safe client-server communication. Each subproject (android/ios/server/web) includes the prerequisite step related to code generation and assumes that one is already in its subdirectory. It is necessary to learn about the openapi specification to comprehend client-server communication and how it is made consistent. The guide I would like you to take a look at is by Brian NQC at Medium: https://medium.com/@briannqc/backend-101-a-guide-to-openapi-and-api-first-approach-c25297226905. If you would like to get a more thorough and more formal introduction to OpenAPI you can also read https://learn.openapis.org/introduction.html.
Server/Backend (server/)#
The backend is writing in golang. If you need a quick start on how to write golang code, check out the amazing https://gobyexample.com/hello-world resource. The project uses modern golang primitives which require golang version 1.23 or higher. If you already have go and want to make sure everything will work, run go version
. Otherwise, to install golang, run:
sudo snap install go --classic
for Linux, depending on your version of Ubuntu, the go package offered by apt might not be new enoughbrew install go
for MacOsscoop install main/git
for Windows Non-WSL
Furthermore, the backend persists data using an SQLite database. Unlike the maybe more familiar PostgreSQL Database Management System that you have used in the Introduction to Databases course, the state of the database is represented as a single file. You don’t start a process that launches the database that you then need to connect to on a given host and port. Starting an SQLite session is as simple as running sqlite3 dbname.db
. You can then run any good old SQL queries that you’ve run on similar systems. To install sqlite3, run:
sudo apt install sqlite3
for Linuxbrew install sqlite
for macOSscoop install main/sqlite
for Windows Non-WSL
The server handles the requests and communication with the database. SplitBit uses ogen to bootstrap all the request, response models, validation and routing based on the openapi.yml spec file. The only thing that needs to be done then is implementing the handler functions that mostly carry out the communication with the database. That communication is facilitated with sqlc which is a thin utility generating type safe code from SQL queries and the db schema. Enter the server
directory using cd server
. Code generation commands are defined within the main.go file. Run go generate
to do the necessary generation. After that in order to build the app you run go build
and ./server
runs the server. Now you clients are ready to interact with it. The server uses data.db file to store the user data. If no file is present, the server will create it on the first run and initialize it with schema.sql. The database will be empty initially, so you can run ./insertSampleData.sh
script to fill it with random but plausible looking data. It will also attempt to install the sqlbs tool (if that fails please install it manually and have it present in the path).
Web Client (web/)#
The web client is written using TypeScript and SvelteKit. Svelte and SvelteKit have their phenomenal tutorials at https://svelte.dev/tutorial/svelte/welcome-to-svelte and https://svelte.dev/tutorial/kit/introducing-sveltekit respectively. SvelteKit builds on top of Svelte to add directory based routing and some other stuff, but we mostly care about this one.
To run the project, you need node and npm. Install with:
sudo apt install nodejs npm
for Linuxbrew install node
for macOSscoop install nodejs
for Windows
Enter the directory with cd web
. Copy file .env.example to .env (cp .env.example .env
) and adjust the URL your client is running at (if you have changed it). Next, run npx openapi-typescript ../openapi.yml -o src/lib/api/schema.ts
to generate API client files for the communication with the server. Finally, run npm install
to get all the dependencies and npm run dev -- --open
to get the client working.
Android Client (android/)#
To develop the android app, you’ll need android studio. Install it by:
sudo snap install android-studio --classic
for Linuxbrew install --cask android-studio
for macOSscoop install extras/android-studio
Check out the resource on creating Jetpack Compose views at: https://developer.android.com/develop/ui/compose/tutorial.
Enter the directory, then create the API client code by running gradle openApiGenerate
to create the API client and the necessary models. Next, open the project in Android Studio and click the run symbol in the top bar or first change the target device to a physical phone if you’ve connected one. By default, it uses a public instance hosted on ISDC’s servers. If you are developing server features at the same time, you might want to change that to make your phone/emulator do its requests to your computer. To do so, modify baseUrl inside src/main/java/fi/isdc_helsinki/splitbit/repositories/ApiClient.kt with the local ip address you get from running commands such as ip address
or ifconfig
AND the port number the server is running on. Then modify the ip address inside app/src/main/res/xml/network_security_config.xml to allow android to make these calls.
iOS Client (ios/)#
To develop the iOS app, you’ll need an actual Mac device. If you really wish to develop it without one, contact me (Mariusz) to help you set up a virtual machine if you have Linux. Open up the project in Xcode and you should be good to go. It doesn’t have any openapi code generation yet so there’s no extra commands to run.