GraphQL 101 Quick Start

GraphQL is the new database management from the Facebook team, which now outsourced. This article is a quick reference from what I’ve learned about it with autodidact. My article may miss some of the concepts as I can’t find a proper “for dummies” tutorial about GraphQL out there but should be sufficient for beginners as a stepping stone for more advanced concepts.

This GraphQL article is made using Graphcool as Server As A Service, and Apollo for the plugins. I’ll try to steer clear from a specific platform implementation, and just focused on GraphQL queries and mutations, as well as how to implement it in Apollo client. Feel free to skip over some steps if you’ve already done it.


  1. Install Homebrew cmd.
  2. Using Homebrew, install npm cmd. brew install node
  3. Using npm, install Graphcool cmd. npm install -g graphcool
  4. Using npm, install Apollo cmd. npm install -g apollo
  5. Create your project.
  6. Incorporate Apollo plugins into your project. iOS | Android | ReactNative
  7. For iOS: add code generation build step for Apollo.

Later when you compiling graphql script using apollo command line, you might notice some warning that basically saying something like “the correct version of Apollo command line to use with this Apollo plugins is 1.8.x”. This is a cue for you to upgrade (or downgrade) the Apollo cmd version to the recommended one, because the version of the Apollo IDE plugin and the version of the Apollo cmd goes hand in hand. You can’t install newer Apollo cmd while using an Apollo IDE plugin that requires an older Apollo cmd version. You can check the available version here (check on the “version” tab), and the example code to install specific version of Apollo cmd using npm is: npm install -g apollo@1.8.x if the warning ask you to install Apollo cmd version 1.8.x. Without upgrading/downgrading Apollo to the correct version to go along with the plugin, your compile might fail.

Create Graphcool Server Mirror

  1. Make your account at Graphcool.
  2. Open terminal command.
  3. Change directory to your project folder.
  4. $ graphcool init server. You can change “server” into your own folder name.
  5. A folder called server will be created, with some premade files. Using terminal, change directory into that folder.

Create GraphQL Models

  1. Within the “server” folder, you can find a bunch of premade files. Of of it is types.graphql. Usually, we will put all of our schema into this file. Schema is like “table structure configuration” equivalent in SQL.
  2. Add the types.graphql into your project.
  3. Open the types.graphql using your IDE.
  4. There are two models already created there, named User and Post. Analyze the code. This should give you a good early example of how to create a model, how to create fields within model with its data type, and how to create a relationship between them.
  5. To create a field with relationship, you have to add the @relation part, following by the relationship identifier. The relationship identifier must appear exactly twice within the whole model structure, because a relationship is between one model to another model.
  6. You can make a relationship one to one, one to many, and many to many. The relation between User and Post illustrate exactly how one to many works, because Post model has one User as owner, but User model has array of Posts. You can deduct how one to one, and many to many relationship works from this.
  7. The great thing about relationship is that if you add a data on one side, then the opposite will also appear on the other side. For example, if you create a Post and set the owner Id, then that Post Id will be automatically appended on the User’s Post with that owner Id.

Deploy Your GraphQL Code Into Graphcool Server

  1. Using the terminal, change directory into the “server” folder (or whatever name you use on graphcool init).
  2. $ graphcool deploy. This will clone your graphcool schema into the server.
  3. At the first time, graphcool deployment will ask you to login to your graphcool account.
  4. It will also ask for which graphcool server you would like to use. Choose the first one.
  5. After that, it will ask for graphcool target name. I usually use my project name + “target”.
  6. And then, it will ask for graphcool service name. This is the name that will appear on graphcool console on their website. Think about it like your database name. I usually use my project name + “service”.
  7. After that, the deployment ensues, and will return your graphcool 3 APIs. The one you need to take note is the “Simple API” one, as that’s what we’re going to use.

Download Your GraphQL Schema from Graphcool using Apollo cmd

  1. The great thing about this whole GraphQL + Apollo thing is that it will make your database connection and operation strong typed. That means, you can have type checking when coding instead of trying to figure out whether you have typed the correct field or not at run time.
  2. But writing GraphQL models within your IDE (types.graphql) doesn’t make the IDE automatically receive the memo about the the strong typed checking. You need the schema in types.graphql to be converted into language that your IDE understand. That’s where Apollo comes to spotlight.
  3. Use Apollo to re-download the schema that you have cloned to the graphcool server.
  4. Using terminal, type the following command: $ apollo schema:download --endpoint:<your_graphcool_simple_API_url>
  5. This will create a file named “schema” on the current terminal directory. On iOS, this will be called schema.swift.
  6. Move schema file into your project root folder. In iOS, this is *not* referring to the directory where your *.xcproject or *.xcworkspace resides. But, in the folder where your info.plist resides.

Generate API File

  1. Compile your project.
  2. If everything goes well, the project will be compiled successfully, and a new file (in iOS named API.swift) will appear in the same directory as schema file.
  3. Add the API file to your project.
  4. This API file is what enables the strong type checking on your project. This API file will be recreated every time you hit the compile. But right now, the API is empty because you haven’t write any single graphql function.

Start Writing GraphQL Functions

  1. Create a new .graphql file in your project.
  2. Within this file, you can begin with either query syntax, or mutation syntax. Query syntax is for you to retrieve data, while mutation syntax is for you to make changes to the data (while also get returned affected data as well).
  3. Read here for GraphQL query and mutation tutorial.
  4. You can try to fiddle around with queries and mutations using Graphcool playground. It’s even equipped with autocomplete!
  5. One thing that you should note that writing queries and mutations within the playground differ than writing queries and mutations in the IDE, mainly because in the playground, you do not have external sources of data to put into your queries/mutations. You hardcoded everything into the script. While in the IDE, you will want to supply the data from your controller into the queries/mutations before fire them to the server. For that, you need to learn that you can give your query/mutation a name, along with passing parameters, which name usually prefixed with $ sign. This is the guide for it for iOS | Android | ReactNative.
  6. After you have written your queries/mutations, you can compile your project. If everything goes correctly, you will see some code magically appears on your API file. You then can use classes created in the file to fire queries/mutations within your own native code with strong type checking.

Some Patterns in Composing GraphQL Queries and Mutations

  • Let’s use the original data model User and Post created by Graphcool init server.
  • If you want to query one object from a table using its ID, call its table name. Ex: user (id: "your_id") { id, name }.
  • If you want to query all objects from a table, call all + table name + “s” (plural form). Ex: allUsers { id, name }.
  • If you want to query all objects from a table, then filter it, add filters to the parameter. Ex: allUsers (filter { name: "your_name_data" }) { id, name }. Read more about filter here.
  • If you want to create a new object into a table, add create + table name. Ex: createUser (name: "John Doe") { id, name }. You don’t need to supply ID field, as it’s automatically created by default.
  • If you want to update existing object data, add update + table name. Ex: updateUser (id: "id_object_to_be_updated", name: "Jane Doe") { id, name }.
  • If you want to append relationship connection into existing relationship array, use add + table name + field name + “Id” + “s”. Ex: addUserPostsIds (userId: "user_id", postId: "post_id") { User { id, name } }.
  • If you want to delete an object from a table, add delete + table name. Ex: deleteUser (id: "id_object_to_be_deleted_here") { id, name }.
  • If you want to remove relationship connection, use remove + table name + field name + “Id” + “s”. Ex: removeUserPostsIds (userId: "user_id", postId: "post_id") { User { id, name } }

This post is far from complete, and just serve as quick reference point for me. Hope this can help you as well. If you have a question, feel free to leave comment. I’ll help you if I can.

iOS Swift Troubleshooting: Cannot Load Underlying Module For

alamofire import error


You see an awesome cocoapod you want to include in your project. So you add a code to your podfile telling it to import the cocoapod, you run “pod install” on your terminal to begin the import process, and voila, the cocoapod now inserted to your project. But when you add the namespace “import framework” on top of your Swift file, Xcode said “Cannot Load Underlying Module For <Framework>”.


The easiest explanation is that because you just import the cocoapod, it still hasn’t been built yet, while the other cocoapods in your project have. Therefore, Xcode sometimes overlooks that there is one or two cocoapods that are new.

  1. Optional: If there’s any, comment out any “import <framework>” statement
    In this abnormal state, this statement may gets processed first before Xcode process whether there are any unbuilt pods or not.
  2. Optional: Clean up the build folder.
    This will force Xcode to rebuild everything from scratch, and not playing favorite.
  3. Optional: Completely quit Xcode, and reopen it, then reopen the project again.
    Sometimes the issue is that the Xcode editor can’t let go of the mistakes in the past.
  4. Rebuild the project.
  5. Optional: Uncomment all the “import <framework>” earlier.
  6. Run the project.

So actually the solution to this is just do rebuild first, not run. The optional steps are there if you have run the solution without the optional steps and it’s still not working. For me, I had to clean build folder and close the Xcode, but I didn’t have to comment out the “import <framework” statement. But some people did have to.

Sources / Read More

Tax Amnesty Dengan Serba-serbi Kasusnya


English reader: This article is talking about tax amnesty that, by the time this article is written, is currently ongoing on Indonesia. This article is written in Bahasa Indonesia. Thank you.

Oke, jadi ceritanya gua barusan ikut workshop tentang tax amnesty. Ngga ada rencana mau ikut sih sebenarnya. Tetapi ternyata memang dapet banyak informasi yang menurut gua cukup berguna sih tentang apa itu sebenarnya tax amnesty, dan tentang perpajakan Indonesia pada umumnya. Ternyata gua yang merasa kira-kira cukup mengetahui apa itu tax amnesty, waktu ikut workshop nya, baru sadar kalau yah walaupun perkiraan gua tentang apa itu tax amnesty itu ngga jauh-jauh amat, tetapi ternyata ada detil-detil yang penting yang tidak akan gua ketahui kalau ngga ikut workshop ini. Tadi coba browsing di internet tentang beberapa detil pun juga tidak bisa nemu.

Nah, gua kan hobi nyatet nih. Jadi di sini mau sharing aja sih apa-apa aja tadi yang sempat gua catet. Moga-moga bisa berguna juga buat temen-temen ya. Siapa tahu ada yang seperti gua, punya feeling tahu apa itu tax amnesty, tapi ternyata tidak tahu. Lol. Dan juga sempat nyatet beberapa kasus-kasus tax amnesty, yang mungkin menarik untuk dipelajari, kali aja ada yang punya kasus yang sama. Btw, karena ini notes, mungkin tulisannya agak tidak keruan. Jadi mohon dimaklumi, diambil intinya saja, oke? 😀

Continue reading

Bookmarks: How to Solve “Could Not Set Up iCloud Keychain” Issue



Apple was (is) notoriously eager to introduce yet another security layer for the iCloud. Yesterday, I was forced to change my iCloud password, which resulted in some login problem with all of my emails and built in social media accounts on my Mac, even though I have entered the correct password. So with the help of my friend, I decided to log my Mac out the iCloud, and then login back again. The log out process itself was a little bit complex in its own way, but finally I’m able to log out. Then I restart my Mac. After that, I log in my Mac again to the iCloud. The system then tried to activate iCloud features one by one. At the iCloud keychain section, iCloud sent an sms to a number that’s associated with my iCloud, which was a deactivated number. Crap. Trying to change the number itself gave me error “failed to change phone number”. I then tried to find some article to change that number, which I find it here: link.

  1. On your iphone – Setting > iCloud > Keychain
  2. Approve with security code on the passcode step.
  3. Click ‘forgot code’ and then click ‘reset’.
  4. Follow on screen step, you will be able to update your phone number.

After that, I was able to receive the sms with password number to input to my Mac. Voila, my Mac’s iCloud was setup successfully!

Wait, what’s that notification just showing on my iPhone?

My iPhone asked me to re-login into iCloud keychain. Apparently, now it’s my iPhone turn to be logged out (forcefully) from iCloud. What? But thank God I’ve change the number. So the process is quite similar, but now it’s my Mac approving my iPhone instead. But then I got the error “could not set up icloud keychain”.

What the heck, Apple? So now my iPhone got locked out of iCloud keychain? After several attempts to reactivate the keychain, I was going to give up, but some search then enlighten me into this forum support, which gave information that this issue happened because Apple was issued a 4 digits security code to the iCloud, and later upgrade it into 6 digits. My iCloud code was the 4 digits version. That’s why the authentication kept failing. The question is why right now? Why not before, when the security code was upgraded to 6 digits? But anyway, these are the steps to fix this:

  1. Go to your other device (iPad, iPhone or Mac) and go to iCloud.
    In my case, my Mac has already connected to iCloud. I don’t know what will happen if it hasn’t.
  2. Then go to keychain.
    This keychain is not on the website of the iCloud, but on the system settings of your device.
  3. Then go to advanced.
  4. Then change security code.
  5. Change it with the new six digits system.
  6. Go back to that device you need to signing it to the keychain. And type the same new six digits then you’ll be signed in.

And that’s it. I hope this will helps you too like it helps me. Meanwhile, let’s hope Apple will revise its security so that it’s more streamlined.

Ada Apa Dengan Film Indonesia? (AADC2 Review)

SPOILER ALERT: This article contains heavy spoilers from the movie “Ada Apa Dengan Cinta 2”. If you haven’t seen it and don’t want to get spoiled, stop reading now.

Oke. Saya baru saja menonton Ada Apa Dengan Cinta 2, karena ditodong oleh istri. 😀 yah, ngga sekejam itu juga sih. Film nya juga lumayan lah. Saya akui, saya jarang-jarang nonton film Indonesia di bioskop. Lebih tepatnya, saya jarang nonton bioskop. Menurut saya, nonton di bioskop itu khusus untuk film-film yang punya banyak special effect, yang efeknya akan hilang bila ditonton di layar kaca. Tetapi karena saya suami yang baik (jiehh) jadi saya mau mencoba menonton film drama Indonesia di bioskop. Dan hasilnya tidak mengecewakan. Saya belum pernah nonton AADC 1. Tetapi film AADC 2 ini ternyata bisa cukup dinikmati tanpa perlu menonton jalan cerita film pertamanya, and that’s a good one, mengingat bahwa kedua film berjarak 14 tahun.
Setelah menonton, sekalipun secara keseluruhan saya nilai filmnya cukup baik, ada beberapa bagian-bagian yang saya merasa ini adalah kelemahan film Indonesia secara umum. Lebih tepatnya, film sinetron Indonesia secara umum, sebab seperti yang saya bilang, saya jarang nonton film Indonesia di bioskop. Kelemahan itu adalah tidak adanya keberanian sutradara dan script writer untuk mengupas konflik emosi secara tuntas dan realistis.

For example, saya bisa merasakan kemarahan Cinta ketika pertama bertemu Rangga, dan saya bisa memahami ketika sedikit demi sedikit perasaan Cinta terbuka terhadap Rangga ketika Rangga mulai menceritakan tentang ibunya yang pergi meninggalkannya. Tapi saya agak merasa aneh ketika tiba-tiba Cinta entah dari mana nyeletuk dengan marah “kamu ngga hubungin aku pasti karena punya perempuan lain ya??” dan tiba-tiba menampar Rangga dan pergi. Belum habis keterkejutan saya, tiba-tiba Cinta beringsut-ingsut datang kembali dan mengatakan untuk mari kita lupakan kejadian di masa lalu, kemudian mengajak berjabat tangan.

What. The. Hell.

I totally could not relate to their feeling at all at that time. Si Cinta itu jadinya mau marah atau mau memaafkan atau mau bikin stand up comedy?? Oke lah kalau itu mungkin celah yang dipaksakan ada untuk iklan Aqua pada adegan setelahnya. Tapi saya sama sekali tetap tidak bisa relate bagaimana bisa Cinta tiba-tiba dari simpatik menjadi marah lalu simpatik lagi seperti tidak ada apa-apa di sepanjang jalan selanjutnya.

Lalu saya juga tidak begitu suka dengan resolusi dari film ini. Cinta akhirnya dengan Rangga, bukan dengan Trian, padahal mereka sudah engaged. Menurut akal sehat, tidak fair dong bila kemudian Cinta berakhir dengan Rangga, bukan dengan Trian. Rangga adalah masa lalu Cinta, tidak peduli apapun alasan Rangga. Apalagi Cinta sekarang sudah hampir jadi ‘milik’ orang lain. Kalau film ini berakhir dengan Cinta bersama Trian, sekalipun berakhir bittersweet, film ini akan punya pesan dan makna yang lebih baik. Saya memang sempat sempat berpikir, ketika Trian memilih untuk mengangkat telepon saat sedang makan bersama Cinta, ketimbang mendengarkan apa yang Cinta ingin katakan, saya berpikir “Waw, orangnya cukup berambisi juga ya untuk bekerja. Apakah dia memang benar-benar orang yang tepat untuk Cinta?” Tetapi mengingat dia sudah ada bersama Cinta selama beberapa lama, dan dia juga sudah mengusahakan hubungan dengan Cinta, fair nya sih Cinta pasti sudah menghitung untung rugi nya untuk tetap jalan dengan Trian selama itu, apalagi mereka sudah sampai engaged.

Selanjutnya, ketika di adegan agak terakhir, ketika Trian memergoki Rangga yang buru-buru keluar dari galeri Cinta karena Cinta menolaknya. Jelas pasti Trian sebagai pria normal akan menginterogasi Cinta, dan saya sudah ‘menunggu’ adegan tersebut, apakah Cinta bisa ‘lolos’ dari hal ini dengan baik? Bagaimanakah pemeran utama film ini akan menangani ketika dia diposisikan sebagai tokoh yang bersalah dalam cerita ini? Tapi ternyata scene tiba-tiba di cut menjadi Cinta mengendarai mobil mengejar kepergian Rangga.

Again. What the hell.

Konklusi yang saya dapat malahan: oh karena saya sudah tertangkap basah dengan Rangga, jadi mending sekalian Trian saya tinggal untuk pergi kepada selingkuhan saya. Jadi Rangga jadi the last resort oleh karena Trian sudah tidak mau lagi padanya, padahal Rangga juga adalah penyebab semua ini terjadi? Jadi kalau Cinta disakiti hatinya, dia bebas untuk marah-marah pada Rangga, tapi kalau Trian yang disakiti hatinya, dia bebas untuk pergi dari Trian? Oh cmon, you can do better than this, Indonesian scriptwriter! Jangan oleh karena mengejar ‘target’ bahwa Cinta harus bersama Rangga, maka alur emosinya menjadi tidak logis. Itu kalau saya tambah satu adegan yaitu Trian yang sedih dan merenung kenapa Cinta tega-teganya mengkhianati dia, maka Cinta akan langsung dengan sukses berubah dari tokoh protagonis menjadi tokoh antagonis lho. Jangan oleh karena Trian adalah pemeran pembantu maka perasaan Trian menjadi tidak penting untuk dieksplorasi! Saya tidak bisa menikmati adegan akhir antara Cinta dengan Rangga oleh karena saya terus kepikiran Trian. Pesan apa yang mau disampaikan kepada generasi ini kalau film yang sedang hot yang ditujukan pada kaum remaja sampai dewasa saja begini pesannya?

Jangan salah. Saya menyukai film ini. Saya suka dengan hubungan persahabatan antara Cinta dengan teman-temannya. Bahkan adegan Cinta bertengkar dengan Carmen pun sempat membuat saya menitikkan air mata. Tapi kecacatan dalam beberapa konflik-konflik yang justru puncak inilah yang membuat saya tidak bisa menikmati film ini dengan baik, bahkan ending dari film ini tidak terasa rewarding karena justru yang saya lihat dari adegan terakhir itu adalah perselingkuhan dan pengkhianatan.

Kira-kira sekian dari saya. Post ini saya buat demi kemajuan film Indonesia juga. Kalau anda punya pandangan atau masukan, silahkan sampaikan di kolom komentar. Terima kasih. Maju terus perfilman Indonesia!

Bekerjalah Roh Kudus (GMS Live “I Declare”) Cover

I Declare

Alright, GMS Live “I Declare” Album has been out last Saturday. Feels like forever since I preordered that album. 😀 Here’s my rendition of “Bekerjalah Roh Kudus”, I’ve translated the song into English so for you who doesn’t speak Indonesian or want to know how this song looks like using English language, here it is. 🙂

Bekerjalah ya Roh Kudus

Roh Kudus hadir di sini
Pribadi yang menawan dan suci
Kurindu mendekat mengerti hatiMu
Berjalan dalam kehendakMu

Roh Kudus manis dan lembut
Penolong yang sejati dan suci
Kurindu mendekat mengerti hatiMu
Berjalan dalam kuasaMu

Bekerjalah ya Roh Kudus
Bertahtalah lebih lagi
UrapanMu, lawatanMu
Kaulah yang kuperlu
Kau terutama di hidupku

Holy Ghost You’re welcomed in this place
I stand in awe of Your glorious divine
How I long to draw near, and listen to Your heart
I want to walk my day in Your cause

Holy Ghost You captivate my heart
Divine Counselor You’re faithful and sincere
How I long to draw near, and listen to Your heart
I want to walk my life in Your power

Holy Spirit fall on this place
Be glorified and magnified
Your anointing overflows me
You are all that I need
Let You be the center of my life

How to Zoom Your iOS Simulator to Arbitrary Scale


How to do:

  1. Quit simulation if open.
  2. Open terminal (from spotlight for example, type terminal).
  3. Paste this next text to the terminal and press enter. Change the 0.4 to any scale you wish (with 0.4 equals to 40%).
    defaults write ~/Library/Preferences/ SimulatorWindowLastScale "0.4"
  4. Or alternatively, go to /Library/Preferences and edit file. Edit value for KEY SimulatorWindowLastScale to desired scale.

I was learning about developing app for iOS. Everything went smoothly so far, except that the iOS simulator display iPhone 6 plus screen which is larger than my MacBook Air screen, even at 50% zoom. I’ve been searching so far on the internet and every answer always saying the same thing: to use CMD+1, CMD+2, CMD+3 shortcut to change the zoom, which is not enough for me. Then I came across this brilliant answer which requires some kind of console command to do, but it did the job. But beware, the simulation display result might be a little jaggy.

Tutorial about Basic Implementation of Google Analytics with Multiple Trackers


I have recently tried to implement Google Analytics on a web I’m working on. And it has been an awful experience because there’s so little documentation for people who wants to use multiple trackers. I can’t give a thorough, detailed, and full of picture tutorial about this because that would cost so much time. But I’ll try to cover as much and as detailed as I can.

I’ll assume you know the basic common sense of the internet, have an at least very basic knowledge about Javascript.

Google Analytics

What is Google Analytics? In short, this is a free statistic service offered by Google to analyze the visitors behavior your website. This service can record everything you supply, from how much a page is opened, to what page element the user interacted with, for example, how many the play video button is clicked. Some people finds statistic boring, but in the hands of people who understand statistic, these data can be used to inform which part of the website needs to be improved, or need focus. For example, if we can get the data that user click 1000 times on promotion A banner, and 5000 times on promotion B banner, then that means promotion B banner is more interesting, thus we need more promotion like promotion B than promotion A.

Google Analytics (GA) vs Universal Analytics (UA)

Google Analytics (ga.js) is the obsolete and out of date implementation. The Universal Analytics (analytics.js) is the new and modern implementation. Both developed by Google, and both are Google Analytics. Mindblown? Me too. But just refer them as ga.js and analytics.js, and people around the world will know which one you’re talking about. For this tutorial, we will stick to the newest implementation, analytics.js.

Continue reading

Money Can’t Buy Everything — But Still Important


There’s an ongoing symptoms in the midst of Christian believers nowadays, and its name is Chrometophobia, or fear of money. In this case, it’s not actually fear, but rather, dislikes. The Christian is taught about “for the money is the root of all evil” law, therefore people tends to stay away from activity that can gave them label “money digger”. People feels guilty when they collect money more than what he thought he need. Sorry, did you notice that I wrote the law wrong? Correct. I was deliberately wrote it wrong. The correct one is “for the love of money is the root of all evil”. It’s not the money that is wrong, but it’s our attitude toward the money that can make it the root of all evil. People sometimes giving up opportunities and saying “I dislikes money. It’s the root of all evil,” kind of things. But actually, more often than not, it’s because they’re covering up for their lack of motivation by giving excuses that looks religious.

Continue reading