SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
From system engineer
to GOPHER
I-Fan@XRSPACE
2021/07/28
coscup.ifan.tw
About ME
Back-end engineer @ XRSPACE,
Newbie to Golang and back-end
Android system software engineer @ XRSPACE,
Developed world first 5G VR HMD
Outline
• System Software Engineer vs Back-end Engineer
• Why Golang
• Clean Architecture with Golang
• Scratch an API server
System Software Engineer
vs
Back-end Engineer
System Software Engineer
ID
Android Device(Phone, HMD)
Hardware
Bootloader
Android Framework
Tools
Linux & Device Driver
HAL
Android Libs
Android Runtime
Android APP
From device bring-up to
software tool for device,
The scope of my work.
What’s system software engineer
(android)
A “Working” System
New request
Tracing lot of source code
Add little piece of codes
Customized System
DRM Playback.
Plain android system.
Tracing android/kernel + DRM module + base non-hlos
source code.
Enable/Modify related source code to integrate DRM
module into system.
A android system capable of DRM playback
Back-end Engineer
What’s software engineer in my
imagination
Silicon Valley S01E05
A Mac with fancy tools that used to code at Starbucks
Discussing and Prototyping
New idea
Write some code
Test and validation
Developed a system
Back-end
Engineer
More time for discussing and prototyping.
More coding and I am building something
from scratch,
it’s delightful.
Why Golang
• One of the newest language
• Developer community
• Performance
• Statically typed
• Great for back-end development
• Effective Go
• Modern grammar
• Build-in test
• Go fmt
• Go vet
Why Golang
Clean Architecture
Clean Architecture with Golang
• Independent of Frameworks
• Testable
• Independent of UI
• Independent of Database
• Independent of any external agency
Clean Architecture with Golang
• The Dependency Rule
• Dependencies can only point inwards,
nothing in an inner circle can know
anything at all about something in an
outer circle.
• Dependency inversion principle
Clean Architecture with Golang
• The Dependency Rule
• Dependencies can only point inwards,
nothing in an inner circle can know
anything at all about something in an
outer circle.
• Dependency inversion principle
Clean Architecture with Golang
• Pros
• Same concept as DDD(Domain)
• Flexibility
• Testability
• Maintenance
• Cons
• Learning curve
• encapsulation, inheritance and
polymorphism everywhere!
• Heavy(compare to Monolithic)
Scratch an API server
Scratch an API server
User
API
SERVER
Database
AWS S3
File
Access URL
Save Meta
Save File
coscup.ifan.tw
Scratch an API server
Controller
Storage
Client
Domain
Application
REST
MongoDB
AWS S3
Repository
coscup.ifan.tw
Scratch an API server
Controller
Storage
Client
Domain
Application
REST
MongoDB
AWS S3
Repository
type AssetID string
type AssetType int
type Asset struct {
FileSize int64
Type AssetType
UploadedTime time.Time
TransferredTime time.Time
ID AssetID
Status AssetStatus
FileName string
Label string
Description string
hashedFileName string
}
Scratch an API server
Domain
- Define asset data structure
domain/asset.define.go
Scratch an API server
The order of fields in struct matters
type myStruct struct {
myInt bool // 1 byte
myFloat float64 // 8 bytes
myBool int32 // 4 bytes
// this takes 24 byte
}
type myStructOptimized struct {
myFloat float64 // 8 bytes
myInt int32 // 4 bytes
myBool bool // 1 byte
// this takes 16 byte
}
Memory
Allocation
type Repository interface {
Save(asset Asset) error
}
type StorageClient interface {
Save(ctx context.Context, fileName string)
(string, error)
}
Scratch an API server
Domain
- Define interfaces for external
layers to follow it
- Interfaces for repository
- Interface for storage
client
domain/asset.define.go
package application
package domain package repository
Scratch an API server
Dependency inversion principle? How?
type Repository {} struct
type Asset {} struct
package repository
type Repository struct {}
func (repo *Repository)Save(a Asset){}
package domain
type Asset struct {}
References
package application
asset := Asset{}
repo := Repository{}
repo.Save(asset)
package application
package domain package repository
Scratch an API server
Dependency inversion principle? How?
type Repository {} struct
type Asset {} struct
package repository
type Repository struct {}
func (repo *Repository)Save(a Asset){}
package domain
type Asset struct {}
type Repository interface{
Save(a Asset)
}
package application
asset := Asset{}
repo := domain.Repository
repo.Save(asset)
type Repository interface {
Save(a Asset)
}
References
Inherits
Scratch an API server
Controller
Storage
Client
Domain
Application
REST
MongoDB
AWS S3
Repository
type Asset struct {
FileSize int64 `bson:"file_size,omitempty"`
Type int64 `bson:"type,omitempty"`
UploadedTime time.Time `bson:"uploaded_time,omitempty"`
ModifyTime time.Time `bson:"modify_time,omitempty"`
TransferredTime time.Time `bson:"transferred_time,omitempty"`
ID string `bson:"id,omitempty"`
Status string `bson:"status,omitempty"`
FileName string `bson:"file_name,omitempty"`
XRID string `bson:"xrid,omitempty"`
Label string `bson:"label,omitempty"`
Description string `bson:"description,omitempty"
HashedFileName string `bson:"hashed_file_name,omitempty"`
}
Scratch an API server
Repository
- Define data
structure to
save to
MongoDB
repository/mongodb/asset.go
type assetRepo struct {
collection *mongo.Collection
ctx context.Context
}
func (repo *assetRepo) Save(asset domain.Asset) error {
result := Asset{}
err := copier.Copy(&result, &asset)
if err != nil { … }
result.HashedFileName = asset.HashedFileName()
filter := bson.M{
"id": asset.ID,
}
update := bson.M{"$set": &result}
opts := options.Update().SetUpsert(true)
_, err = repo.collection.UpdateOne(repo.ctx, filter,
update, opts)
return err
}
Scratch an API server
Repository
repository/mongodb/asset.go
- Implement Save()
Scratch an API server
Controller
Storage
Client
Domain
Application
REST
MongoDB
AWS S3
Repository
type S3StorageClient struct {
channel chan io.Reader
…
}
func (s S3StorageClient) Save(ctx context.Context, fileName string) (string,
error) {
…
file, ok := <-s.channel
if ok != true { … }
res, err := s.uploader.UploadWithContext(ctx, &s3manager.UploadInput{
Body: file,
Bucket: aws.String(s.bucket),
Key: aws.String(fileName),
})
if err != nil { … }
return res.Location, nil
}
Scratch an API server
Storage Client
storageclient/asset.go
- Implement Save()
Scratch an API server
Controller
Storage
Client
Domain
Application
REST
MongoDB
AWS S3
Repository
coscup.ifan.tw
type UploadFileCommand struct {
FileSize int64
FileName string
Label string
Description string
TransferredTime time.Time
UploadedTime time.Time
}
type UploadFileResult struct {
HashedFileName string
AssertURL string
AssetStatus string
ID string
}
Scratch an API server
Application
application/command.go
- Define upload command and response
type AppService struct {
repo domain.AssetRepository
storageClient domain.AssetStorageClient
}
func NewAssetAppService(repo domain.Repository,
storageClient domain.StorageClient)
*AppService {
return &AppService{
repo: repo,
storageClient: storageClient,
}
}
Scratch an API server
Application
application/application.srv.go
- Define service struct and constructor
func (assetApp *AppService) UploadFile(command UploadFileCommand) (*UploadFileResult, error) {
ts := time.Now()
asset, err := domain.NewAsset(domain.NewAssetParam{
ID: assetApp.repo.NewID(),
FileName: command.FileName,
FileSize: command.FileSize,
Status: domain.AssetStatusUploaded,
UploadedTime: command.UploadedTime,
Description: command.Description,
Label: command.Label,
})
if err != nil {…}
err = assetApp.repo.Save(*asset)
if err != nil {…}
urlAsset, err := assetApp.storageClient.Save(context.Background(), asset.HashedFileName())
if err != nil {…}
asset.Transferred(asset.UploadedTime.Add(time.Now().Sub(ts)))
err = assetApp.repo.Save(*asset)
if err != nil {…}
return &UploadFileResult{
HashedFileName: asset.HashedFileName(),
AssertURL: urlAsset,
ID: string(asset.ID),
AssetStatus: string(asset.Status),
}, nil
}
Scratch an API server
Application
application/application.srv.go
- Implement
function for
upload usecase
Scratch an API server
Controller
Storage
Client
Domain
Service
REST
MongoDB
AWS S3
Repository
coscup.ifan.tw
func (a *Asset) Upload(ctx *gin.Context) {
label := ctx.PostForm("label")
description := ctx.PostForm("description")
fileAsset, headerAsset, err := parseUploadFiles(ctx,
"asset")
if err != nil {}
ch := make(chan io.Reader, 1)
defer close(ch)
ch <- fileAsset
client, err := storageclient.NewStorageClient(config,
ch, time.Second*5)
if err != nil {}
repoAsset := a.sys.GetRepository().Asset()
appSrv := application.NewAssetAppService(repoAsset,
client)
cmd := application.UploadFileCommand{
FileName: headerAsset.Filename,
Label: label,
FileSize: headerAsset.Size,
Description: description,
}
result, err := appSrv.UploadFile(cmd)
if err != nil {}
ctx.JSON(200, gin.H{"success": result.AssertURL
,})
}
Scratch an API server
Controller
- Translate input request to
internal data format
- Wake application up for work
domain/asset.define.go
Save
Repository
Upload
Application
Save
Storage Client
POST /upload
Controller
Asset
Domain
Used by
Used by
Used by
Used by Injected interface{}
Independent test to
database/storage
Independent test to
repository/storage
Independent test to
application
Top layer can be used
every where
Demo
Source code:
coscup.ifan.tw
What I have learned
• The working model as is totally different from system
engineer.
• Never hesitate to refactor or even abandon your code, always
refine it.
• It’s important to learn it with fine architecture or design
pattern, it might to tough but it’s worth.
Thank you.
linkedin.com/in/ifan-wang
w07fan@gmail.com

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

YARN Services
YARN ServicesYARN Services
YARN Services
 
Serverless Architectural Patterns & Best Practices
Serverless Architectural Patterns & Best PracticesServerless Architectural Patterns & Best Practices
Serverless Architectural Patterns & Best Practices
 
Getting Started with Docker on AWS - DevDay Los Angeles 2017
Getting Started with Docker on AWS - DevDay Los Angeles 2017Getting Started with Docker on AWS - DevDay Los Angeles 2017
Getting Started with Docker on AWS - DevDay Los Angeles 2017
 
Kubernetes API code-base tour
Kubernetes API code-base tourKubernetes API code-base tour
Kubernetes API code-base tour
 
Aws lambda best practices - ignite - dev opsdays-charlotte
Aws lambda   best practices - ignite - dev opsdays-charlotteAws lambda   best practices - ignite - dev opsdays-charlotte
Aws lambda best practices - ignite - dev opsdays-charlotte
 
AWS Lambda: Best Practices and Common Mistakes - AWS Community Days 2019
AWS Lambda: Best Practices and Common Mistakes - AWS Community Days 2019AWS Lambda: Best Practices and Common Mistakes - AWS Community Days 2019
AWS Lambda: Best Practices and Common Mistakes - AWS Community Days 2019
 
Intro to Batch Processing on AWS - DevDay Los Angeles 2017
Intro to Batch Processing on AWS - DevDay Los Angeles 2017Intro to Batch Processing on AWS - DevDay Los Angeles 2017
Intro to Batch Processing on AWS - DevDay Los Angeles 2017
 
Building a chatbot – step by step
Building a chatbot – step by stepBuilding a chatbot – step by step
Building a chatbot – step by step
 
Kubernetes Networking in Amazon EKS (CON412) - AWS re:Invent 2018
Kubernetes Networking in Amazon EKS (CON412) - AWS re:Invent 2018Kubernetes Networking in Amazon EKS (CON412) - AWS re:Invent 2018
Kubernetes Networking in Amazon EKS (CON412) - AWS re:Invent 2018
 
KubeCon EU 2018 – Sig API Machinery Deep Dive
KubeCon EU 2018 – Sig API Machinery Deep DiveKubeCon EU 2018 – Sig API Machinery Deep Dive
KubeCon EU 2018 – Sig API Machinery Deep Dive
 
Introduction to ACI APIs
Introduction to ACI APIsIntroduction to ACI APIs
Introduction to ACI APIs
 
Run Kubernetes with Amazon EKS - SRV318 - Chicago AWS Summit
Run Kubernetes with Amazon EKS - SRV318 - Chicago AWS SummitRun Kubernetes with Amazon EKS - SRV318 - Chicago AWS Summit
Run Kubernetes with Amazon EKS - SRV318 - Chicago AWS Summit
 
Scaling terraform
Scaling terraformScaling terraform
Scaling terraform
 
Aci programmability
Aci programmabilityAci programmability
Aci programmability
 
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
 
AWS Batch: Simplifying Batch Computing in the Cloud
AWS Batch: Simplifying Batch Computing in the CloudAWS Batch: Simplifying Batch Computing in the Cloud
AWS Batch: Simplifying Batch Computing in the Cloud
 
A Customized Approach to HTTP Proxy Caching in Ruby
A Customized Approach to HTTP Proxy Caching in RubyA Customized Approach to HTTP Proxy Caching in Ruby
A Customized Approach to HTTP Proxy Caching in Ruby
 
Origins of Serverless
Origins of ServerlessOrigins of Serverless
Origins of Serverless
 
AWS Container services
AWS Container servicesAWS Container services
AWS Container services
 
2021 JCConf 使用Dapr簡化Java微服務應用開發
2021 JCConf 使用Dapr簡化Java微服務應用開發2021 JCConf 使用Dapr簡化Java微服務應用開發
2021 JCConf 使用Dapr簡化Java微服務應用開發
 

Ähnlich wie From System Engineer to Gopher

Ähnlich wie From System Engineer to Gopher (20)

Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
 Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
Serverless Framework Workshop - Tyler Hendrickson, Chicago/burbs
 
Build a Node.js Client for Your REST+JSON API
Build a Node.js Client for Your REST+JSON APIBuild a Node.js Client for Your REST+JSON API
Build a Node.js Client for Your REST+JSON API
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
 
High quality ap is with api platform
High quality ap is with api platformHigh quality ap is with api platform
High quality ap is with api platform
 
Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018
Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018
Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018
 
Alex Casalboni - Configuration management and service discovery - Codemotion ...
Alex Casalboni - Configuration management and service discovery - Codemotion ...Alex Casalboni - Configuration management and service discovery - Codemotion ...
Alex Casalboni - Configuration management and service discovery - Codemotion ...
 
Application Lifecycle Management in a Serverless World | AWS Public Sector Su...
Application Lifecycle Management in a Serverless World | AWS Public Sector Su...Application Lifecycle Management in a Serverless World | AWS Public Sector Su...
Application Lifecycle Management in a Serverless World | AWS Public Sector Su...
 
Continuous Integration e Delivery per (r)innovare lo sviluppo software e la g...
Continuous Integration e Delivery per (r)innovare lo sviluppo software e la g...Continuous Integration e Delivery per (r)innovare lo sviluppo software e la g...
Continuous Integration e Delivery per (r)innovare lo sviluppo software e la g...
 
Build A Killer Client For Your REST+JSON API
Build A Killer Client For Your REST+JSON APIBuild A Killer Client For Your REST+JSON API
Build A Killer Client For Your REST+JSON API
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
 
Serverless Development Deep Dive
Serverless Development Deep DiveServerless Development Deep Dive
Serverless Development Deep Dive
 
Supercharge Your Product Development with Continuous Delivery & Serverless Co...
Supercharge Your Product Development with Continuous Delivery & Serverless Co...Supercharge Your Product Development with Continuous Delivery & Serverless Co...
Supercharge Your Product Development with Continuous Delivery & Serverless Co...
 
Building CICD Pipelines for Serverless Applications
Building CICD Pipelines for Serverless ApplicationsBuilding CICD Pipelines for Serverless Applications
Building CICD Pipelines for Serverless Applications
 
Application Lifecycle Management in a Serverless World
Application Lifecycle Management in a Serverless WorldApplication Lifecycle Management in a Serverless World
Application Lifecycle Management in a Serverless World
 
AWS April Webinar Series - Getting Started with Amazon EC2 Container Service
AWS April Webinar Series - Getting Started with Amazon EC2 Container ServiceAWS April Webinar Series - Getting Started with Amazon EC2 Container Service
AWS April Webinar Series - Getting Started with Amazon EC2 Container Service
 
Amazon ECS Deep Dive
Amazon ECS Deep DiveAmazon ECS Deep Dive
Amazon ECS Deep Dive
 
Amazon Amazon Elastic Container Service (Amazon ECS)
Amazon Amazon Elastic Container Service (Amazon ECS)Amazon Amazon Elastic Container Service (Amazon ECS)
Amazon Amazon Elastic Container Service (Amazon ECS)
 
Introduction to DevOps on AWS
Introduction to DevOps on AWSIntroduction to DevOps on AWS
Introduction to DevOps on AWS
 
AWS18 Startup Day Toronto- The Best Practices and Hard Lessons Learned of Ser...
AWS18 Startup Day Toronto- The Best Practices and Hard Lessons Learned of Ser...AWS18 Startup Day Toronto- The Best Practices and Hard Lessons Learned of Ser...
AWS18 Startup Day Toronto- The Best Practices and Hard Lessons Learned of Ser...
 
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Node Interactive: Node.js Performance and Highly Scalable Micro-ServicesNode Interactive: Node.js Performance and Highly Scalable Micro-Services
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
 

Kürzlich hochgeladen

CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 

Kürzlich hochgeladen (20)

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 

From System Engineer to Gopher

  • 1. From system engineer to GOPHER I-Fan@XRSPACE 2021/07/28 coscup.ifan.tw
  • 2. About ME Back-end engineer @ XRSPACE, Newbie to Golang and back-end Android system software engineer @ XRSPACE, Developed world first 5G VR HMD
  • 3. Outline • System Software Engineer vs Back-end Engineer • Why Golang • Clean Architecture with Golang • Scratch an API server
  • 6. ID Android Device(Phone, HMD) Hardware Bootloader Android Framework Tools Linux & Device Driver HAL Android Libs Android Runtime Android APP From device bring-up to software tool for device, The scope of my work. What’s system software engineer (android)
  • 7. A “Working” System New request Tracing lot of source code Add little piece of codes Customized System DRM Playback. Plain android system. Tracing android/kernel + DRM module + base non-hlos source code. Enable/Modify related source code to integrate DRM module into system. A android system capable of DRM playback
  • 9. What’s software engineer in my imagination Silicon Valley S01E05 A Mac with fancy tools that used to code at Starbucks
  • 10.
  • 11. Discussing and Prototyping New idea Write some code Test and validation Developed a system Back-end Engineer More time for discussing and prototyping. More coding and I am building something from scratch, it’s delightful.
  • 13. • One of the newest language • Developer community • Performance • Statically typed • Great for back-end development • Effective Go • Modern grammar • Build-in test • Go fmt • Go vet Why Golang
  • 15. Clean Architecture with Golang • Independent of Frameworks • Testable • Independent of UI • Independent of Database • Independent of any external agency
  • 16. Clean Architecture with Golang • The Dependency Rule • Dependencies can only point inwards, nothing in an inner circle can know anything at all about something in an outer circle. • Dependency inversion principle
  • 17. Clean Architecture with Golang • The Dependency Rule • Dependencies can only point inwards, nothing in an inner circle can know anything at all about something in an outer circle. • Dependency inversion principle
  • 18. Clean Architecture with Golang • Pros • Same concept as DDD(Domain) • Flexibility • Testability • Maintenance • Cons • Learning curve • encapsulation, inheritance and polymorphism everywhere! • Heavy(compare to Monolithic)
  • 19. Scratch an API server
  • 20. Scratch an API server User API SERVER Database AWS S3 File Access URL Save Meta Save File coscup.ifan.tw
  • 21. Scratch an API server Controller Storage Client Domain Application REST MongoDB AWS S3 Repository coscup.ifan.tw
  • 22. Scratch an API server Controller Storage Client Domain Application REST MongoDB AWS S3 Repository
  • 23. type AssetID string type AssetType int type Asset struct { FileSize int64 Type AssetType UploadedTime time.Time TransferredTime time.Time ID AssetID Status AssetStatus FileName string Label string Description string hashedFileName string } Scratch an API server Domain - Define asset data structure domain/asset.define.go
  • 24. Scratch an API server The order of fields in struct matters type myStruct struct { myInt bool // 1 byte myFloat float64 // 8 bytes myBool int32 // 4 bytes // this takes 24 byte } type myStructOptimized struct { myFloat float64 // 8 bytes myInt int32 // 4 bytes myBool bool // 1 byte // this takes 16 byte } Memory Allocation
  • 25. type Repository interface { Save(asset Asset) error } type StorageClient interface { Save(ctx context.Context, fileName string) (string, error) } Scratch an API server Domain - Define interfaces for external layers to follow it - Interfaces for repository - Interface for storage client domain/asset.define.go
  • 26. package application package domain package repository Scratch an API server Dependency inversion principle? How? type Repository {} struct type Asset {} struct package repository type Repository struct {} func (repo *Repository)Save(a Asset){} package domain type Asset struct {} References package application asset := Asset{} repo := Repository{} repo.Save(asset)
  • 27. package application package domain package repository Scratch an API server Dependency inversion principle? How? type Repository {} struct type Asset {} struct package repository type Repository struct {} func (repo *Repository)Save(a Asset){} package domain type Asset struct {} type Repository interface{ Save(a Asset) } package application asset := Asset{} repo := domain.Repository repo.Save(asset) type Repository interface { Save(a Asset) } References Inherits
  • 28. Scratch an API server Controller Storage Client Domain Application REST MongoDB AWS S3 Repository
  • 29. type Asset struct { FileSize int64 `bson:"file_size,omitempty"` Type int64 `bson:"type,omitempty"` UploadedTime time.Time `bson:"uploaded_time,omitempty"` ModifyTime time.Time `bson:"modify_time,omitempty"` TransferredTime time.Time `bson:"transferred_time,omitempty"` ID string `bson:"id,omitempty"` Status string `bson:"status,omitempty"` FileName string `bson:"file_name,omitempty"` XRID string `bson:"xrid,omitempty"` Label string `bson:"label,omitempty"` Description string `bson:"description,omitempty" HashedFileName string `bson:"hashed_file_name,omitempty"` } Scratch an API server Repository - Define data structure to save to MongoDB repository/mongodb/asset.go
  • 30. type assetRepo struct { collection *mongo.Collection ctx context.Context } func (repo *assetRepo) Save(asset domain.Asset) error { result := Asset{} err := copier.Copy(&result, &asset) if err != nil { … } result.HashedFileName = asset.HashedFileName() filter := bson.M{ "id": asset.ID, } update := bson.M{"$set": &result} opts := options.Update().SetUpsert(true) _, err = repo.collection.UpdateOne(repo.ctx, filter, update, opts) return err } Scratch an API server Repository repository/mongodb/asset.go - Implement Save()
  • 31. Scratch an API server Controller Storage Client Domain Application REST MongoDB AWS S3 Repository
  • 32. type S3StorageClient struct { channel chan io.Reader … } func (s S3StorageClient) Save(ctx context.Context, fileName string) (string, error) { … file, ok := <-s.channel if ok != true { … } res, err := s.uploader.UploadWithContext(ctx, &s3manager.UploadInput{ Body: file, Bucket: aws.String(s.bucket), Key: aws.String(fileName), }) if err != nil { … } return res.Location, nil } Scratch an API server Storage Client storageclient/asset.go - Implement Save()
  • 33. Scratch an API server Controller Storage Client Domain Application REST MongoDB AWS S3 Repository coscup.ifan.tw
  • 34. type UploadFileCommand struct { FileSize int64 FileName string Label string Description string TransferredTime time.Time UploadedTime time.Time } type UploadFileResult struct { HashedFileName string AssertURL string AssetStatus string ID string } Scratch an API server Application application/command.go - Define upload command and response
  • 35. type AppService struct { repo domain.AssetRepository storageClient domain.AssetStorageClient } func NewAssetAppService(repo domain.Repository, storageClient domain.StorageClient) *AppService { return &AppService{ repo: repo, storageClient: storageClient, } } Scratch an API server Application application/application.srv.go - Define service struct and constructor
  • 36. func (assetApp *AppService) UploadFile(command UploadFileCommand) (*UploadFileResult, error) { ts := time.Now() asset, err := domain.NewAsset(domain.NewAssetParam{ ID: assetApp.repo.NewID(), FileName: command.FileName, FileSize: command.FileSize, Status: domain.AssetStatusUploaded, UploadedTime: command.UploadedTime, Description: command.Description, Label: command.Label, }) if err != nil {…} err = assetApp.repo.Save(*asset) if err != nil {…} urlAsset, err := assetApp.storageClient.Save(context.Background(), asset.HashedFileName()) if err != nil {…} asset.Transferred(asset.UploadedTime.Add(time.Now().Sub(ts))) err = assetApp.repo.Save(*asset) if err != nil {…} return &UploadFileResult{ HashedFileName: asset.HashedFileName(), AssertURL: urlAsset, ID: string(asset.ID), AssetStatus: string(asset.Status), }, nil } Scratch an API server Application application/application.srv.go - Implement function for upload usecase
  • 37. Scratch an API server Controller Storage Client Domain Service REST MongoDB AWS S3 Repository coscup.ifan.tw
  • 38. func (a *Asset) Upload(ctx *gin.Context) { label := ctx.PostForm("label") description := ctx.PostForm("description") fileAsset, headerAsset, err := parseUploadFiles(ctx, "asset") if err != nil {} ch := make(chan io.Reader, 1) defer close(ch) ch <- fileAsset client, err := storageclient.NewStorageClient(config, ch, time.Second*5) if err != nil {} repoAsset := a.sys.GetRepository().Asset() appSrv := application.NewAssetAppService(repoAsset, client) cmd := application.UploadFileCommand{ FileName: headerAsset.Filename, Label: label, FileSize: headerAsset.Size, Description: description, } result, err := appSrv.UploadFile(cmd) if err != nil {} ctx.JSON(200, gin.H{"success": result.AssertURL ,}) } Scratch an API server Controller - Translate input request to internal data format - Wake application up for work domain/asset.define.go
  • 39. Save Repository Upload Application Save Storage Client POST /upload Controller Asset Domain Used by Used by Used by Used by Injected interface{} Independent test to database/storage Independent test to repository/storage Independent test to application Top layer can be used every where
  • 41. What I have learned • The working model as is totally different from system engineer. • Never hesitate to refactor or even abandon your code, always refine it. • It’s important to learn it with fine architecture or design pattern, it might to tough but it’s worth.