Transition from an iOS engineer to a backend engineer
This is the December 7 article for Eureka’s 2021 Advent Calendar
Nearly one year ago, I transitioned from an iOS engineer position to a Backend engineer position within the same company, Eureka.
Hopefully, I can provide you with some useful insights regarding the transition from an iOS role to a Backend engineer role by writing and sharing about how I proceed to do it and the different steps taken to catch up the technical skills.
The transition from iOS engineer to backend engineer
I joined Eureka in June 2018 as an iOS Engineer. It’s a company developing the dating application Pairs, which help people find their life partners and Pairs Engage which is a digital and affordable Marriage Matchmaking Agency helping people to marry as soon as possible.
Starting with iOS
As an iOS Engineer working for the Pairs Engage product, my contributions and learning were very diverse. Since I joined the project as it just started, I worked with a team of engineers, designer and product owner to design and implement new features from mapping the user journey, user stories, giving UX and UI ideas to developing and shipping the iOS application for new targets/markets.
On the iOS side, it was an honor to work with the friend and teammate John Estropia leading the iOS development with who I learned a lot.
I got the opportunity to work on very interesting tech stacks from:
- A iOS project architecture that is MVVM/Flux reactive based to provide a single source of truth data-wise
- Making delightful experience through very smooth graphics thanks to libraries such as Texture/AsyncDisplayKit
- Implementing face detection to help center the user’s uploaded profile picture to make it easier to notice his facial profile,
- Many more..
We were sometimes doing study-times and pair programming for knowledge sharing, that sometimes resulted in the creation of multiple open source animations challenges available in Github.
If you’re interested to learn more about those animation challenges, you can read the first one right there about the Bear’s iOS search animation.
Why changing to Backend
I think at some point, I wanted to widen my skillset ( horizontally ). When we create iOS apps, we interact a lot with backend engineers. How data is structured and stored, business logic treated, performances for fetching and manipulating data managed, etc. So I got an interest for this team because I thought that as someone with an iOS experience, I may know what may or may not be convenient for front engineers, etc. And learning how things on the API side are done behind the scene are simply interesting.
What’s similar and what’s different
When I started working on API tasks, little by little I started seeing similarities or sometimes big differences both in the way of thinking and the programming languages themselves.
Programming languages differences
Both Swift and Go lang are statically typed, meaning that we need to know the type of properties during compile time, whether it’s inferred or set explicitly, which is good for coding safely 😇.
// go
s := "Hello" // type of `s` is `string`----// swift
let s = "Hello" // type of `s` is `String`
It’s difficult to compare both languages because they are made for different purpose.. Go was apparently made to be scaled across multiple processor which explain its native support for concurrency through only one keyword go yourFunction()
, as well as being able to communicate between goroutine using channels, native support for web servers, etc..
In term of language features, in my opinion Swift wins with many features, such as:
- Optional types, which is Swift-way that help you avoid nil pointer exceptions errors as much as possible.
Another example is if you have embed type with nullable properties.
Also, in addition to Optional types:
- Inheritance
- Generics ( coming soon with go! )
- The possibility to add custom operators for any types
- Enum cases and the possibility to check at compile-time that your
switch-case
is not missing any possible values from your enumeration.. - Many more..
Different challenges
Both platforms have theirs very different challenges
iOS:
Device and iOS Compatibility: supporting old iOS versions to keep as much users as possible, updating the app to resolve the issues that may happen with a new iOS version, fixing layout issues when a new device with a very small or big screen is released, deciding when to stop supporting a specific iOS version, etc.. All those things takes time and work.
App Store rejection: Releasing is not about just pushing a button, it’s about hopping that the released version will not be rejected on the App Store, that it’s not going to be delayed by days before it’s approved..
High Expectations of UX/UI, Graphics: In order to fulfill the user’s need, an important amount of work regarding the experience of an application, its usability, how easy and smooth it is to do something is one of the important challenges that front engineers in general need to deal with.
And many more..
Backend:
Scalability and resilience. Compared to an iOS app where there is usually only one user logged in, servers, depending on the company, have to support a load of millions/hundred of thousands/dozens of thousands/thousands users connected and using the API services at the same time.
So I would say in general, if you can delegate heavy work from your server to someone else, that would be beneficial for your server CPU/memory consumption.
For example, if the server is using Amazon Web Services (AWS) S3 to upload images in buckets and in the case where it’s common for the client to upload heavy pictures on your server, then instead of asking the iOS client to send you a heavy base64 picture or through a multipart request, in which situation both the client and the server have to deal with a considerable amount of resources/memory usage, AWS S3 come up with a nice feature called Pre-signed URL that will allow the client to upload the image directly at a specific URL, thus delegating the work from the server to AWS.
Another example: if one of your database for example is down, having a way to quickly resolve the situation is important. It’s common to have replication of database ( multiple “slave” databases ) that will all have copy of the main (master) database and will always be synchronized ( with a little delay ). Every time a request to fetch data is executed, instead of asking the master database, one of the slave database will be used instead, thus dividing the charge of work.
Infrastructures costs. Since a tons of users may be logged in and using the API services, making sure in general to choose the most optimized solution for an implementation is important as the cost/resource consumption increase proportionally to the number of users using the service. So if you’re implementing for example a login frequency implementation, then make sure for example to compare the pro/cons between different services in term of costs and server resource consumption depending on your needs e.g data has a lifespan, etc. ( MySQL? Amazon AWS DynamoDB? other? )
And many more..
How did the transition from an iOS Engineer to a Backend Engineer happened within my company Eureka
- Sharing with the manager
I took the first step by sharing what I wanted to do with my manager. I wanted to have his opinion. A few months later, after meeting with the manager of the Backend team, we agreed on the start date.
When I started, I was exchanging closely with the CTO kaneshin and from there a friend and lead backend engineer James Kirk took me under his arms and mentored me all the way till now.
From this graph which kinda summarize some of the important skillsets to have as a Backend engineer, we took it into account as well as the existing tech stacks of our Pairs Engage API project, and we started working on a side project first while being mentored.
2. Started working on a side project first while being mentored
In order to catch up with the minimum required skills to start being productive as soon as possible, working on projects/small tasks and learning fast was necessary.
James Kirk invited me in a weekly 1~2h pair programming meeting that we had and kept for most of the year ( lucky me! )
a) We first looked at the basics or base setup of a server app, meaning what are the things that need to be understood and implemented as soon as someone start a new project.
In a different and new project made specially for experimenting and learning, after having done an interactive introduction to the Go language, we covered some basics things like:
- How environment variable are used within the project for local development: the fact that with environment variable, your project configuration including sensitive data ( API keys, tokens, etc. ) are not stored in your repo but locally in a env/envrc file
- Go mod or how to manage dependencies within a Go Lang project
- The life of an HTTP request in a Go server where we took a look at handlers, middleware, etc.
- Panic handling or how to recover when something bad happens in a request that could crash the server, such as an unhandled fatal error.
- How to implement a Graceful Shutdown through Go’s Signal and Channel mechanisms in order to safely and properly shutdown resources/tasks/connections when the server needs to be turned off.
- And many more..
b) We then moved to the next step that covered:
- Clean Architecture whose ideas/patterns are used within the project. Hands on on implementing a constraint-based architecture where very layer should be independent and testable as much as possible that would allow for example to easily replace any frameworks that we are using, replacing any databases, etc. — -> see more below about it
- The use of Docker and Localstack. Playing with AWS services freely could sometimes be dangerous cost-wise 😅, and since not all of the services have an easy way to work locally on our computer, Localstack was used in the side project in order to be able to interact with different AWS services such as AWS S3, DynamoDB, etc.
- Learning on my side through Udemy classes..
c) From that, I then worked on small tasks that includes bug fixes, code improvement etc in order to get familiar with the project’s code.
As the tasks got bigger and bigger, and I was getting more and more familiar with the project’s code thanks to my team PR reviews and feedbacks and coaching, I started taking in charge bigger and bigger features that were rolled out in production to our users. Again, those tasks were really diverses. Those tasks included for example:
- Reducing the charge of our server for multiple image uploading by using Pre-signed AWS S3 URLs, which delegated the role to upload the image from the server to the client.
- Designing DynamoDB table to implement a login frequency feature ( last 10 days )
- Resolving N+1 problems
- etc..
Hopefully, those insights regarding how I proceed to transition and the different steps taken to catch up the skills and learned were useful for you.
So from those info, don’t hesitate to go talk to your manager if you want to try, and try to find a mentor that can help guide you at the beginning, that would be very helpful!
I would like to thanks my company Eureka for being very encouraging regarding this transition and their support.
We’re hiring in Japan. You can find the list of jobs there.
If you’re interested, don’t hesitate to send me a private message on my twitter account: aymenworks