Building a Credit System w/ Prisma (Pt. 3)
Alrighty, we’re gonna keep keeping on.
In the last chapter we got our boilerplate for creating our application server done. If you want to get caught up on this series, checkout Part 1 here and Part 2 here.
Just like the last post, I’m going to write code and write this post at the same time!
Now I want to integrate our data access tier (the apis we generated with Prisma) into our service tier (the application server we built in the last chapter). The way we can do that is by using GraphQL Bindings
Bindings
GraphQL bindings are an amazing way to create an SDK to your GraphQL api. This allows you to embed and use the APIs of a GraphQL server into another application.
Prisma exposes a binding called prisma-binding
, which we will embed into our application server to leverage the apis we generated in the data access layer.
$ yarn add prisma-binding
We’re going to take our prisma
service’s endpoint and add the prisma binding to the context of our application server:
Let’s go reimplement our getBalance
query actually hooked up to our data access layer.
First I’m gonna go create a CreditAccount
in the prisma graphiql UI
mutation {
createCreditAccount(data: {
userId: "HELLO",
balance: 4
}) {
id
userId
balance
}
}
So our access pattern to get this data is going to be by userId
so we can write our getBalance resolver like this:
Damn that is a dope developer experience. Getting this data was so easy:
Design Time
Alright, I’m going to sketch out in our service schema all the APIs I want to support for this system.
So I definitely do not want to copy types from my data access layer into the service layer. I did some research and it looks like I can use a tool called graphql-import
to import types from other schemas into this one! Solid
$ yarn add graphql-import
Oh, I think this may have already been a dependency of another tool? Maybe the cli. Anyway…
I want to add two more queries to the service layer
# import PricingTable from './generated/prisma.graphql'getPricingTable(pricingTableId: ID!): PricingTable
Given a pricing table Id, I want to hide the prisma query syntax from the consumer. Just give me and ID and I’ll give you a pricing table.
# import Price from '../generated/prisma.graphql'
# import TransactionItemCreateInput from '../generated/prisma.graphql'preparePurchase(items: [TransactionItemCreateInput]): Price
Given items that are part of your transaction, and if you need a little refresh, TransactionItems contain SKUs
the thing we are selling. This will spit out the Price
we need to pay! In our current starter case, we want to exchange US cents for Virtual Currency. But we could use this query again to exchange Virtual Currency for WHATEVER we want.
Alright, time to add some mutations
# import PricingTable from '../generated/prisma.graphql'createPricingTable(pricingTableId: ID!, description: String!, skuIds: [ID!]!): PricingTable
Cool, given some metadata about what we’re selling, we can make a pricing table. I’d probably lock down this API with some permission checks to see if the user is allowed to create pricing tables.
# import TransactionItemCreateInput from '../generated/prisma.graphql'purchase(items: [TransactionItemCreateInput], description: String!, paymentMethod: ID!, paymentAmount: Int): Int
This is probably the core api to the whole service. Given transaction items, a payment method, and the paymentAmount created from preparePurchase
, buy something! Not sure how I am going to use paymentMethod. Will probably have to talk to stripe or some other payment platform to fulfill the purchase.
Here’s the full schema I’m laying out: https://github.com/abhiaiyer91/prisma-credits/blob/master/src/schema/service-schema.graphql
Alright, time for bed. Will pick this up later :)